2011-02-02 93 views
2

我有一個Windows應用程序。我們已經實施了AutoSave功能作爲後臺進程。在特定時間間隔後執行任務的最佳做法是什麼?

示例代碼如下:

While(1) 
{ 
    Thread.Sleep(60000) // 1 minute sleep 
    DoAutoSaveAllControls(); 
} 

我認爲這是壞的功能。糾正我,如果我錯了。但是,我想提高性能並在一定的時間間隔後執行此任務,而不需要執行Sleep。 另外,在後臺進程中做到這一點很好嗎?

+0

另請參閱此相關的問題:[比較使用了Thread.Sleep和定時器延遲執行(http://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for延遲執行) – 2011-02-02 11:18:42

回答

4

更好的方法是使用計時器。您可以瞭解從這個優秀的文章在.NET框架中的各種不同的定時器:

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

您正在使用的WinForms,所以System.Windows.Forms.Timer會就好了你。

例如:

System.Windows.Forms.Timer tmrWindowsFormsTimer = new System.Windows.Forms.Timer(); 
tmrWindowsFormsTimer.Interval = TimeSpan.FromMinutes(1); 
tmrWindowsFormsTimer.Tick += new EventHandler(tmrWindowsFormsTimer_Tick); 
tmrWindowsFormsTimer.Start(); 


private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgs e) { 
    tmrWindowsFormsTimer.Stop(); 
    DoAutoSaveAllControls(); 
} 

這將停止計時器第一跳後,有效地火一次計時器。

0

Thread.Sleep根本不影響性能。爲了我完全可以,但由於您的應用程序可能在UI線程中修改了文檔,因此您可能需要對保存進行修改以避免併發修改。只是因爲這個原因,使用Timer而不是BackGroundWorker會更好。

+0

「while + sleep」解決方案通過始終佔用線程確實會損害性能。確定在客戶端中,在服務器應用程序中無法接受。 – 2011-02-02 11:17:53

+0

由於諸多原因,Thread.Sleep是個不好的解決方案。 [有趣的相關閱讀](http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx)。 – 2011-02-02 11:20:16

0

你說得對,它不是一個很好的使用線程。看看Timer課程。

0

我想你需要從調用代碼中觸發保存功能(知道是否有任何變化已經發生)。因此,保存線程可以確定調用線程已經做了一些更改以保存。

這不是這個問題的答案,只是可能的建議。因此,如果您從定時器內部調用Save,則應首先驗證是否發生了任何更改。要做到這一點,你需要一些額外的變量,這對於工作線程和保存線程是很常見的。如果工作線程確實改變了某些東西,它會觸發該變量爲true。保存時,如果var爲true - 則需要保存。保存後 - 將common var更改爲false。

0

您可以使用System.Timers.Timer一定的時間間隔後啓動一個進程,檢查樣品片段

aTimer = new System.Timers.Timer(10000); 

    // Hook up the Elapsed event for the timer. 
    aTimer.Elapsed += new ElapsedEventHandler(YourHandlerMethod); 

    // Set the Interval to 2 seconds (2000 milliseconds). 
    aTimer.Interval = 2000; 
    aTimer.Enabled = true; 
2

可以使用無Extenssions此爲well.It看起來更自然,你可以結合可觀。

var observable = Observable.Timer(
        TimeSpan.FromMinutes(1), 
        TimeSpan.FromMinutes(1)).Timestamp(); 

    using (observable.Subscribe())) 
    { 
     DoAutoSave(); 
    } 
相關問題