Should I always use Task.Delay instead of Thread.Sleep? [duplicate]

筅森魡賤 提交于 2019-12-30 10:05:04

问题


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).

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);
}

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

  • 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.

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()?


回答1:


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.

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.

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 uses a System.Threading.Timer internally which also has a resolution of ~15ms.



来源:https://stackoverflow.com/questions/29356139/should-i-always-use-task-delay-instead-of-thread-sleep

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!