2014-09-30 80 views
0

我想要一個線程每500毫秒執行一次方法。但是,我希望這發生在單個線程上 - 我不希望它在線程池上運行。所以,System.Timer和System.Threading.Timer是不可能的。有沒有這樣做的標準方式?線程週期性調用沒有線程池的方法

+0

你有沒有嘗試'Thread.Sleep' while'while循環? – BradleyDotNET 2014-09-30 23:33:18

+1

它每次都在同一個線程上完成它的功能是什麼? – jmcilhinney 2014-09-30 23:34:55

+0

你的主線程在做什麼?它是在消息泵(在這種情況下,WinForms或WPF)還是它是一個控制檯應用程序? – 2014-09-30 23:35:00

回答

4

你可以做一個循環是這樣的:

var sw = Stopwatch.StartNew(); 
while (youStillWantToProcess) 
{ 
    DoYourStuff(); 

    while (sw.Elapsed < TimeSpan.FromMilliseconds(500)) 
     Thread.Yield(); // Or Thread.Sleep(10) for instance if you can afford some inaccuracy 

    sw.Restart(); 
} 

Thread.Yield通話將告訴OS調度CPU暫時在不同的線程。您的線程將保留在活動線程列表中,儘管它可以快速恢復處理。

類似,可能更好,方法是:

var sw = Stopwatch.StartNew(); 
var spinWait = new SpinWait(); 

while (youStillWantToProcess) 
{ 
    DoYourStuff(); 

    spinWait.Reset(); 
    while(sw.Elapsed < TimeSpan.FromMilliseconds(500)) 
     spinWait.SpinOnce(); 

    sw.Restart(); 
} 

看看在SpinWait結構。它實現了一個不同的邏輯:這將是很短的時間非常積極的,過了一點時間,它會開始Yield,然後Sleep(0)最後Sleep(1)

從源代碼:

// These constants determine the frequency of yields versus spinning. The 
// numbers may seem fairly arbitrary, but were derived with at least some 
// thought in the design document. I fully expect they will need to change 
// over time as we gain more experience with performance. 
internal const int YIELD_THRESHOLD = 10; // When to switch over to a true yield. 
internal const int SLEEP_0_EVERY_HOW_MANY_TIMES = 5; // After how many yields should we Sleep(0)? 
internal const int SLEEP_1_EVERY_HOW_MANY_TIMES = 20; // After how many yields should we Sleep(1)? 

你問的準確性,所以這裏你有它,但老實說,使用旋轉等待500毫秒的週期感覺有點奇怪...