首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在sync方法中暂停执行的Task.Delay或Thread.Sleep

在sync方法中暂停执行的Task.Delay或Thread.Sleep
EN

Stack Overflow用户
提问于 2019-05-21 07:10:58
回答 1查看 1.1K关注 0票数 1

我想暂停同步方法。我知道我可以使用:

代码语言:javascript
复制
// SAMPLE 01
Thread.Sleep(30 * 1000)

但它有一个缺点,那就是阻塞当前线程。另一个选择

代码语言:javascript
复制
// SAMPLE 02
await Task.Delay(30 * 1000)

将仅在异步方法中工作。但我需要在同步方法中使用它。我们不能这样做

代码语言:javascript
复制
// SAMPLE 03
Task.Delay(30 * 1000).Wait()

因为它可能导致死锁(至少我是这么认为的)。我的最终解决方案是

代码语言:javascript
复制
// SAMPLE 04
Task.Run(() => Task.Delay(30 * 1000)).Wait();

最后,我的问题是:这个解决方案(SAMPLE 04)真的比SAMPLE 01 (使用Thread.Sleep)更好吗?

加分问题:SAMPLE 03真的可以做死锁吗?如果我们这样做:

代码语言:javascript
复制
// SAMPLE 05
Task.Delay(30 * 1000).Wait(30 * 1000)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-21 08:22:21

这个解决方案(样本04)真的比样本01 (使用Thread.Sleep)更好吗?

不是的。更糟的是。样本01更容易理解,效率也更高。

它的缺点是阻塞当前线程。

Thread.Sleep确实阻塞了当前线程。在异步方法中,这将是一个缺点。

我需要在同步方法中使用它。

然后,根据定义,您希望阻塞当前线程。这就是同步的含义。

事实上,您的所有示例都阻塞了调用线程(除了02,它是异步的)。与Thread.Sleep一样,Wait也会阻塞调用线程。

SAMPLE 03真的可以做死锁吗?

不是的。为了产生死锁,你需要两个不同的东西互相等待,然后它们才能继续。对于classical sync-over-async deadlock,你需要做的两件事是:

  1. async方法,其await已捕获单线程上下文。
  2. 在同一上下文中阻塞的线程。

在您的示例中,您有一个线程被阻塞。让我们假设有一个单线程上下文,该线程在该上下文中被阻塞。您仍然不会有死锁,因为Task.Delay方法没有捕获它的上下文。这样就不会出现死锁了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56229244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档