2013-04-08 91 views
17

我真的很为此苦苦挣扎。我在visual studio中创建了一个winforms应用程序,并且需要一个每隔半小时滴答一次的后台计时器 - 这样做的目的是从服务器下载更新。创建一个异步运行的后台定时器

我已经尝试了几种不同的方法,但由于教程/示例较差或者由于我自己的缺陷C#而失败了。我认为,如果看起来我所尝试的远远不够,我会浪费时间向你展示我所尝试的内容。

有没有人知道一个简单明了的方法来实现一个易于被C#新手理解的异步后台计时器?

+2

我假设你正在使用'System.Timers.Timer'? – 2013-04-08 12:52:59

+2

在我看来,最重要的问题是:定时器运行时会发生多少工作?这会对你的计划的回应有什么影响。请注意,所有WinForms应用程序都在一个UI线程中运行,如果该线程突然忙于从服务器拉取一些数据,而用户可能不喜欢它,那么问题是否需要多线程解决方案? – Siraf 2013-04-08 12:55:20

+0

这不是一个特别沉重的过程。只需从服务器获取数据表,然后根据表的内容运行一些SQL。大多数情况下,无论如何什么都不会返回。 – 2013-04-08 13:03:13

回答

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)

参见:Why does a System.Timers.Timer survive GC but not System.Threading.Timer?

+2

这是最简单的方法。 +1 – 2013-04-08 13:00:24

+0

我的天啊,太简单了!需要有更好的例子可以更容易地找到。谢谢! – 2013-04-08 13:10:09

+2

你可以进一步简化它:'timer.Elapsed + = OnTimedEvent;'你可能会失去'新的ElapsedEventHandler'部分。 – 2013-04-08 13:14:46

4

我认为你需要了解所有的定时器类。请参阅Jon的答案。

你使用什么样的计时器?

  1. System.Windows.Forms.Timer将在UI线程
  2. System.Timers.Timer执行一个线程池线程执行,除非你 指定SynchronizingObject的
  3. System.Threading.Timer执行其在线程池线程中回调

在所有情况下,计时器本身都是异步的 - 它不会“占用”线程直到它被触发。

来源:

System.Timers.Timer theTimer; 

在窗体加载(或任何你需要开始更新轮询其他时间),这样做:在您的形式Do .NET Timers Run Asynchronously?

+2

-1:答案是乔恩答案的逐字转载。因此,作为评论会更合适。 – 2013-04-08 12:58:27

+0

通常情况是这样,但是我们正在谈论Jon Skeet。 +1。 – 2017-09-29 02:12:37

10

申报的成员变量

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

声明你的PollUpdates成员函数是这样的:

private void PollUpdates(object sender, EventArgs e) 
{ 
} 
+0

抱歉可能重复从米奇小麦的答案,我已经发布它同时:) – 2013-04-08 13:02:49

+0

是的,但无论如何感谢!不幸的是,我只能标记出一个被接受的答案,并且由于mitch先回答,我只标记他的答案是公平的。但我已经为你的+1了 - 谢谢:) – 2013-04-08 13:11:24

相关问题