2014-09-30 102 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毫秒的周期感觉有点奇怪...