尘叶心繁

.net Thread.Sleep长时间睡眠的问题

电脑版发表于:2021/2/2 11:08

.netcore

.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.AutoResetEventSystem.Timers.Timer类结合。以下是在无限循环中使用TimerAutoResetEvent的示例,该循环是错误使用Thread.Sleep的最常见地方。

  1. /// <summary>
  2. /// 我们将它设置10秒调度一次
  3. /// </summary>
  4. static readonly System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(10).TotalMilliseconds) { AutoReset = true };
  5. /// <summary>
  6. /// 我们将第一次不让它过让它为false
  7. /// </summary>
  8. static readonly AutoResetEvent autoResetEvent = new AutoResetEvent(false);
  9. static void Main(string[] args)
  10. {
  11. timer.Elapsed += Timer_Elapsed;
  12. timer.Start();
  13. ThreadPool.QueueUserWorkItem((state) =>
  14. {
  15. while (true)
  16. {
  17. Console.WriteLine(DateTime.Now);
  18. autoResetEvent.WaitOne();
  19. }
  20. });
  21. Console.ReadLine();
  22. }
  23. /// <summary>
  24. /// 调度的事件
  25. /// </summary>
  26. /// <param name="sender"></param>
  27. /// <param name="e"></param>
  28. private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
  29. {
  30. autoResetEvent.Set();
  31. }

实际上,我们不必依赖Thread.Sleep切片,而是可以使用Timer设置事件并安排Thread执行。由于它是AutoResetEvent而不是ManualResetEvent,因此一旦线程执行,我们将自动重置事件。

关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
猜你喜欢
    1. 1
    2. 2
    / 2