2013-04-08 29 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