【问题标题】:Is there any other use for Thread.Sleep() besides simulating long-lasting tasks?Thread.Sleep() 除了模拟持久任务之外还有其他用途吗?
【发布时间】:2014-04-25 22:51:00
【问题描述】:

我发现 Thread.Sleep() 在模拟长期任务并以优雅的方式取消它们时非常有用(避免 Thread.Abort()),另一方面,我已经阅读了使用 Thread .Sleep() 等待其他操作结束是一种不好的做法(我们有 Thread.Join() 来做这件事)。我想知道 Thread.Sleep() 在实际生产代码/情况中是否有任何应用。

【问题讨论】:

  • 即使对于您希望能够取消的长期任务,通常也有更好的选择 - 通常,您将能够访问一些对象,该对象公开了一个接受的 Wait 方法某种时间跨度参数。这样做的好处是,当需要取消时,响应是立即,而不是您选择的任何粒度Sleep at。
  • @Damien:在我的情况下,一个 bool 变量足以取消线程任务中的循环,因此它几乎立即返回。我在测试时使用了 Thread.Sleep(),但是我在编译之前删除了 Sleeps,所以我在生产代码中没有使用 Sleeps。

标签: multithreading language-agnostic


【解决方案1】:

这里有几个:

  1. Sleep(0) 引发上下文切换,让位于另一个同等或更高优先级的等待线程。
  2. 有时,您不想使用计时器。计时器滴答声可以同时发生,并且计时器不能可靠地停止。在计时器由于竞争条件而停止后,您可以接收无限多的滴答声(即滴答声可能会排队并稍后交付)。如果您希望每分钟执行一个操作,睡眠循环是一种有效的解决方案。
  3. 操作限制。也许您只想在有配额的情况下询问 Twitter。

【讨论】:

【解决方案2】:

当然。如果规范说要等待 5 秒,在某个函数的某个地方,Sleep(5000) 对我有用,例如:

'启动压缩机后,等待五秒钟让压力稳定后再打开燃油阀'。

经常被嘲笑的 Sleep() 调用确实有一些优点。它不涉及其他线程来运行计时器。它适用于所有线程上任何深度的任何调用堆栈的任何位置。它不需要将现有代码重写为状态机。

OTOH:它经常被滥用来轮询线程间标志,而不是使用更合适和更少浪费的线程间信号。 Sleep(0) 和 Sleep(1) 循环通常只是浪费时间、CPU 和内存带宽。

【讨论】:

    【解决方案3】:

    这取决于你是否想要阻塞线程。 Thread.Sleep() 会阻塞线程。

    例如,如果您有一个线程在某处发送请求,但突然连接断开,那么您可以使用Thread.Sleep() 稍等片刻再重试(这可能是暂时的连接错误),这很有用。

    正如我所说,它会阻塞线程,因此线程被冻结,其他人无法使用它。 或者,您可以使用await Task.Delay() 并释放该线程以执行其他操作,直到给定的超时到期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-14
      • 2010-10-25
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 2023-02-09
      相关资源
      最近更新 更多