.net Thread.Sleep长时间睡眠的问题
电脑版发表于:2021/2/2 11:08
.net Thread.Sleep长时间睡眠的问题
在工作中,不知道大家有没有发现,Thread.Sleep
如果设置的时间过长,会导致它就像人睡着了一样到点了都不醒过来。但如果你在它睡眠的时候去按一下回车键多按几下,它就醒了。这就会让我觉得它要长时间睡眠后不能保证我的服务得以正常的运行。网友说:它仅保证将线程至少暂停这么多秒,因为它基于针对不同Windows版本的时间片编号。具体问题可以看看这个:https://blogs.msmvps.com/peterritchie/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program/
解决问题
那么如何解决呢?我们可以通过调度的方式来解决。在最高级别上,您可以使用Quartz.NET
库,但是如果您不需要任何大的逻辑来安排执行时间,那么这会有些负担。
可以使用的一件事是 System.Threading.AutoResetEvent
与System.Timers.Timer
类结合。以下是在无限循环中使用Timer
和AutoResetEvent
的示例,该循环是错误使用Thread.Sleep
的最常见地方。
/// <summary>
/// 我们将它设置10秒调度一次
/// </summary>
static readonly System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(10).TotalMilliseconds) { AutoReset = true };
/// <summary>
/// 我们将第一次不让它过让它为false
/// </summary>
static readonly AutoResetEvent autoResetEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
timer.Elapsed += Timer_Elapsed;
timer.Start();
ThreadPool.QueueUserWorkItem((state) =>
{
while (true)
{
Console.WriteLine(DateTime.Now);
autoResetEvent.WaitOne();
}
});
Console.ReadLine();
}
/// <summary>
/// 调度的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
autoResetEvent.Set();
}
实际上,我们不必依赖Thread.Sleep
切片,而是可以使用Timer
设置事件并安排Thread
执行。由于它是AutoResetEvent
而不是ManualResetEvent
,因此一旦线程执行,我们将自动重置事件。