我想有一个每500毫秒执行一次方法的线程。但是,我希望这发生在一个线程上 - 我不希望它在线程池上运行。因此,System.Timer和System.Threading.Timer是不可能的。有没有一种标准的方法呢?
答案 0 :(得分: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
调用将告诉操作系统暂时在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毫秒的时间感觉有些奇怪......