Создание фонового таймера для асинхронного запуска

18

Я действительно борюсь с этим. Я создаю приложение winforms в visual studio и нуждаюсь в таймер фона, который тикает один раз каждые полчаса - цель этого - вытащить обновления с сервера.

Я попробовал несколько разных подходов, но они потерпели неудачу, из-за плохого учебника / примеров или моих собственных недостатков в C# . Я думаю, что было бы пустой тратой времени, чтобы показать вам то, что я пробовал, поскольку кажется, что я пробовал довольно далеко.

Кто-нибудь знает о ясном и простом способе реализации асинхронного фонового таймера, который легко понять новичку C# ?

    
задан Mike Baxter 08.04.2013 в 14:48
источник
  • Я предполагаю, что вы используете System.Timers.Timer? –  Jeremy Holovacs 08.04.2013 в 14:52
  • На мой взгляд, самый важный вопрос: сколько работы будет выполняться при запуске таймера? Каким будет эффект от обратной совместимости вашей программы. Обратите внимание, что все приложения WinForms запускаются в одном потоке пользовательского интерфейса, если этот поток становится занятым, вдруг вытаскивая некоторые данные с сервера, вашим пользователям может это не понравиться, поэтому вам нужно многопоточное решение или нет. –  Siraf 08.04.2013 в 14:55
  • Это не особенно тяжелый процесс. Просто захватывает данные с сервера, а затем запускает некоторый SQL, основанный на содержимом таблицы. В большинстве случаев ничего не будет возвращено. –  Mike Baxter 08.04.2013 в 15:03
  • @Terfi: тогда лучше использовать System.Windows.Forms.Timer и System.Windows.Threading.DispatcherTimer. Это удобно, потому что они выполняют свой код в потоке графического интерфейса пользователя, поэтому ему не нужны явные вызовы Invoke. Эти таймеры хороши для быстрого периодического обновления GUI. Если код более длительный, вы должны использовать System.Threading.Timer с явным Invoke только для части обновления –  Sunil 08.04.2013 в 15:25

3 ответа

27
    // Create a 30 min timer 
    timer = new System.Timers.Timer(1800000);

    // Hook up the Elapsed event for the timer.
    timer.Elapsed += OnTimedEvent;

    timer.Enabled = true;


...

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // do stuff
}

с обычными предостережениями: таймер не будет очень точным и может понадобиться GC.KeepAlive(timer)

См. также: Почему System.Timers.Timer выживает GC, но не System.Threading.Timer?

    
ответ дан Mitch Wheat 08.04.2013 в 14:54
источник
  • Это самый простой способ. +1 –  Adam K Dean 08.04.2013 в 15:00
  • Боже мой, это было так просто! Там должны быть лучшие примеры, подобные этому, которые можно найти более легко. Спасибо! –  Mike Baxter 08.04.2013 в 15:10
  • Вы можете упростить его дальше: timer.Elapsed + = OnTimedEvent; Вы можете потерять новую часть ElapsedEventHandler. –  Matthew Watson 08.04.2013 в 15:14
  • Согласно stackoverflow.com/q/4962172/116818, вам не нужно GC.KeepAlive (таймер), таймер делает это сам по себе. –  Victor Grigoriu 21.04.2017 в 12:28
10

Объявите переменную-член в вашей форме:

System.Timers.Timer theTimer;

При загрузке формы (или в другое время, когда вам нужно начать опрос обновлений), выполните:

theTimer = new System.Timers.Timer(1800000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();

Объявите функцию участника PollUpdates следующим образом:

private void PollUpdates(object sender, EventArgs e)
{
}
    
ответ дан the_virt 08.04.2013 в 14:59
источник
  • извините за возможный дубликат ответа от Mitch Wheat, я отправил его в одно и то же время :) –  the_virt 08.04.2013 в 15:02
  • Да, но спасибо в любом случае! К сожалению, я могу только отметить один ответ, как принято, и с тех пор, как сначала ответил митч, справедливо отметить его. Но я добавил +1 к вам - спасибо :) –  Mike Baxter 08.04.2013 в 15:11
4

Я думаю, вам нужно знать обо всех таймерных классах. См. Ответ Джона ниже.

  

Какой таймер вы используете?

     
  1. System.Windows.Forms.Timer будет выполняться в потоке пользовательского интерфейса
  2.   
  3. System.Timers.Timer выполняется в потоке пула потоков, если только вы         укажите объект SynchronizingObject
  4.   
  5. System.Threading.Timer выполняет обратный вызов в потоке пула потоков.
  6.   

Во всех случаях сам таймер будет асинхронным - он не будет «поднимать» поток до тех пор, пока он не загорится.

Источник: Выполняют ли асинхронные таймеры .NET?

    
ответ дан JSJ 08.04.2013 в 14:54
источник
  • -1: ответ - это дословная перепечатка ответа Джона. Таким образом, это было бы более уместно в качестве комментария. –  Mitch Wheat 08.04.2013 в 14:58
  • Обычно это правда, но это Джон Скит, о котором мы говорим. +1. –  Todd Menier 29.09.2017 в 04:12