我应该总是用Task.Delay代替了Thread.Sleep? [英] Should I always use Task.Delay instead of Thread.Sleep?

查看:399
本文介绍了我应该总是用Task.Delay代替了Thread.Sleep?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近看到一些建议,指出 Thread.sleep代码不应该在生产中code(在<二手最近href=\"http://stackoverflow.com/questions/29352170/c-sharp-thread-sleep1000-takes-much-more-than-1000ms-on-some-pc/29352367#comment46891534_29352367\">this SO质疑)。许多倡导使用 Task.Delay 来代替。大多数我发现使用UI应用程序为例,自从优势 Task.Delay 的解释是显而易见的(而不是阻塞UI)。

I have recently seen several recommendations stating that Thread.Sleep should never be used in production code (most recently in this SO question). Many of these advocate for using Task.Delay instead. Most of the explanations I've found use UI applications as examples, since the advantages to Task.Delay are obvious (not blocking the UI).

在我而言,我使用 Thread.sleep代码等待循环内轮询特定条件的WCF服务,如:

In my case, I am using Thread.Sleep inside of a wait loop that polls a WCF service for a particular condition, like this:

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

在这种情况下, Task.Delay 似乎并没有应用以下潜在优势:

In this case, the following potential advantages of Task.Delay seem not to apply:


  • 睡眠时间相对比较大,约15毫秒的典型定时器的分辨率,所以在精度 Task.Delay 的增加似乎微不足道。

  • 这个过程是单线程(非UI),并且必须阻塞,直到条件为真,因此,使用等待没有任何优势在这里。

  • 不需要取消延迟的能力。

  • The sleep time is fairly large relative to the typical timer resolution of around 15 ms, so the increase in accuracy of Task.Delay seems trivial.
  • The process is single-threaded (non-UI) and must block until the condition is true, so using await has no advantage here.
  • The ability to cancel the delay is not required.

这是它是适合使用的情况下 Thread.sleep代码?什么是优势(如果有的话)与替换我的睡眠行 Task.Delay(1000).Wait()

Is this a case where it is appropriate to use Thread.Sleep? What would be the advantage (if any) of replacing my sleep line with Task.Delay(1000).Wait()?

推荐答案

有永远不会在更换的优点 Thread.sleep代码(1000); Task.Delay(1000).Wait(); 。如果你想等到同步只需使用 Thread.sleep代码

There's never an advantage in replacing Thread.Sleep(1000); in Task.Delay(1000).Wait();. If you want to wait synchronously just use Thread.Sleep.

如果你真的只有一个线程和规划,以保持这种状态,那么你可以使用 Thread.sleep代码。不过,我仍然会用 Task.Delay ,因为它是在大多数情况下,preferable,所以它是一个很好的模式。我只将在最高层拦截,当你不能使用异步了,即使这样我会建议使用某种的 AsyncContext

If you really only have a single thread and planning to keep it that way, then you can use Thread.Sleep. However, I would still use Task.Delay as it's preferable in most cases and so it's a good pattern. I would only block at very top when you can't use async anymore, and even then I would suggest using some kind of AsyncContext.

您也可以使用 System.Threading.Timer 直接 * 而不是 Task.Delay 但是你应该记住,定时执行每间隔不会等待实际操作来完成的,因此,如果 ExternalServiceIsReady 花费的时间比间隔可以更有该服务同时多个呼叫。

You can also use a System.Threading.Timer directly* instead of Task.Delay however you should keep in mind that the timer executes every interval and doesn't wait for the actual operation to complete, so if ExternalServiceIsReady takes more than the interval you can have multiple calls to that service concurrently.

一个更好的解决办法是用一个异步操作来代替外部服务的轮询因此该服务可以通知您,当它已经准备好,而不是你问它的每一秒(因为它依赖于该服务并不总是可能的):

An even better solution would be to replace the polling of the external service with an asynchronous operation so the service can notify you when it's ready instead of you asking it every second (that isn't always possible as it depends on the service):

await ExternalServiceIsReadyAsync();


* Task.Delay 使用 System.Threading.Timer 内部也具有15毫秒〜的分辨率。


* Task.Delay uses a System.Threading.Timer internally which also has a resolution of ~15ms.

这篇关于我应该总是用Task.Delay代替了Thread.Sleep?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆