这个问题在这里已有答案:

我最近看到一些建议说明Thread.Sleep永远不应该用在生产代码中(最近在这个SO问题中 )。 其中许多人主张使用Task.Delay 我发现的大多数解释都使用UI应用程序作为示例,因为Task.Delay的优点是显而易见的(不阻止UI)。

在我的例子中,我在一个等待循环内部使用Thread.Sleep来轮询WCF服务的特定条件,如下所示:

DateTime end = DateTime.UtcNow + TimeSpan.FromMinutes(2);
while (DateTime.UtcNow < end)
{
    if (ExternalServiceIsReady() == true)
    {
        return true;
    }
    Thread.Sleep(1000);
}

在这种情况下, Task.Delay的以下潜在优势似乎不适用:

  • 睡眠时间相对于大约15毫秒的典型定时器分辨率相当大,因此Task.Delay准确性增加似乎微不足道。
  • 该进程是单线程(非UI),必须阻塞直到条件为真,因此使用await在这里没有优势。
  • 不需要取消延迟的能力。

这是一个适合使用Thread.Sleep吗? Task.Delay(1000).Wait()替换我的睡眠线会有什么好处(如果有的话) Task.Delay(1000).Wait()

#1楼 票数:7 已采纳

替换Thread.Sleep(1000);永远不会有优势Thread.Sleep(1000); Task.Delay(1000).Wait(); 如果要同步等待,只需使用Thread.Sleep

如果你真的只有一个线程并计划保持这种方式,那么你可以使用Thread.Sleep 但是,在大多数情况下,我仍然会使用Task.Delay ,因此它是一个很好的模式。 当你不能再使用async时,我只会阻止在顶部,即便如此,我建议使用某种AsyncContext

您也可以直接使用System.Threading.Timer *而不是Task.Delay但是您应该记住,计时器执行每个时间间隔并且不等待实际操作完成,因此如果ExternalServiceIsReady需要超过您的间隔时间可以同时多次调用该服务。

一个更好的解决方案是用异步操作替换外部服务的轮询,这样服务就可以在它准备就绪时通知你而不是你每秒都要求它(这并不总是可能的,因为它取决于服务):

await ExternalServiceIsReadyAsync();

* Task.Delay在内部使用System.Threading.Timer ,其分辨率约为15ms。

  ask by BJ Myers translate from so

未解决问题?本站智能推荐:

1回复

我应该总是使用Task.Delay而不是Thread.Sleep吗? [重复]

这个问题在这里已有答案: 何时使用Task.Delay,何时使用Thread.Sleep? 4个答案 我最近看到一些建议说明Thread.Sleep永远不应该用在生产代码中(最近在这个SO问题中 )。 其中许多人主张使用Task.Delay 。 我发现的大多数
2回复

如果Task.Delay比Thread.Sleep更受青睐,为什么本书中的示例使用Thread.Sleep?

我正在阅读Wouter de Kort的考试参考书70-483:《用C#编程》。 作者没有明确提及C#的版本,但我猜是5.0,因为他大量使用了async / await关键字。 本书中的示例仅使用Thread.Sleep(),而不使用Task.Delay() , 等等等
2回复

Thread.Sleep(2500) 与 Task.Delay(2500).Wait()

我想对此有所澄清。 我知道Task.Delay将在内部使用 Timer 并且它显然是基于任务的(可等待的),而Thread.Sleep会导致线程被阻塞。 但是,在任务上调用.Wait会导致线程被阻塞吗? 如果不是,人们会认为Task.Delay(2500).Wait()比Thread.Sleep(
1回复

Task.Delay(-1)有任何用例吗? [重复]

这个问题在这里已有答案: 为什么Task.Delay()允许无限延迟? 3个答案 我想知道Task.Delay(-1)或Task.Delay(TimeSpan.FromMilliseconds(-1))是否有任何用例。 根据各自的文档,该方法创建在完成之前无限期
2回复

Thread.Sleep在Task.Run中

我最近试图了解C#的新async / await和Task.Run功能。 在这样做的过程中,我编写了一些简单的测试代码,这些代码写入控制台,以便我可以看到事情发生的顺序,在这里和那里投入Thread.Sleep以确保事情按照我预期的顺序发生。 这是我的一个测试 使用以下Termi
1回复

Task.Delay永远不会完成

以下代码将永远冻结。 如果我使用注释掉的代码将调用切换到DoSomethingAsync ,它的行为与预期的一样。 我怀疑嵌套等待导致死锁,但我不知道为什么,或者如何解决它。
2回复

Task.Yield()与Task.Delay(0)

Delay(0)总是内联吗? 根据我的经验,它确实: 这是一个控制台应用程序,因此线程池用于继续。 输出:
2回复

我们是否应该使用Task.Delay替换Thread.Sleep

我正在研究新的TPL,以使我自己制作的工作流程更好地工作。 现在,我进入了Task.Delay和Thread.Sleep的迷宫。 因此,Task.Delay(50).Wait()的工作原理与Thread.Sleep(500)一样。 那么我应该在代码中使用哪一个呢? 从Intern
2回复

Task.Delay 值得取消吗?

我最近使用我在许多地方看到的取消模式重新实现了一大堆异步 WCF 服务方法 - 在那里你等待启动任务和Task.WhenAny上的 Task.WhenAny。 当然,现有任务不可取消,但希望在以后的版本中解决。 就我而言, Task.Delay的默认持续时间由服务设置控制。 在绝大多数情况下,结果
1回复

为什么 Thread.Sleep 有效而 Task.Delay 无效?

在我的代码中,我假设outerFlag将在innerFlag之后被击中,但它实际上innerFlag运行而忘记( innerFlag在outerFlag之后被击中)。 当我使用Thread.Sleep而不是Task.Delay标志按正确顺序命中。 这是代码: 我还注意到,当我调用Task.De