线程定期调用不带线程池的方法
本文关键字:线程 方法 调用 | 更新日期: 2023-09-27 18:25:05
我想要一个每500毫秒执行一个方法的线程。但是,我希望这种情况发生在单个线程上——我不希望它在线程池上运行。因此,System.Timer和System.Threading.Timer是不可能的。有标准的方法吗?
您可以执行这样的循环:
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毫秒的旋转等待时间感觉有点奇怪…