Cli*_* Ok 8 c# task thread-safety async-await
我想暂停同步方法。我知道我可以使用:
// SAMPLE 01
Thread.Sleep(30 * 1000)
Run Code Online (Sandbox Code Playgroud)
但它有一个缺点,会阻塞当前线程。另一种选择
// SAMPLE 02
await Task.Delay(30 * 1000)
Run Code Online (Sandbox Code Playgroud)
仅适用于异步方法。但我需要在同步方法中使用它。我们不能这样做
// SAMPLE 03
Task.Delay(30 * 1000).Wait()
Run Code Online (Sandbox Code Playgroud)
因为它可能会导致僵局(至少我是这么认为)。我的最终解决方案是
// SAMPLE 04
Task.Run(() => Task.Delay(30 * 1000)).Wait();
Run Code Online (Sandbox Code Playgroud)
最后,我的问题是:这个解决方案(SAMPLE 04)真的比SAMPLE 01(使用 Thread.Sleep )更好吗?
额外问题:SAMPLE 03真的可以解决死锁问题吗?如果我们这样做怎么办:
// SAMPLE 05
Task.Delay(30 * 1000).Wait(30 * 1000)
Run Code Online (Sandbox Code Playgroud)
此解决方案(示例 04)真的比示例 01(使用 Thread.Sleep)更好吗?
不,情况更糟。示例 01 更容易理解,也更高效。
它的缺点是会阻塞当前线程。
确实Thread.Sleep
阻塞了当前线程。在异步方法中,这将是一个缺点。
我需要在同步方法中使用它。
那么,根据定义,您想要阻止当前线程。这就是同步的意思。
事实上,您的所有示例都会阻塞调用线程(02 除外,它是异步的)。Wait
与调用线程一样阻塞调用线程Thread.Sleep
。
SAMPLE 03 真的可以做死锁吗?
不。为了产生僵局,你需要两个不同的事物互相等待才能继续。对于经典的同步异步死锁,你需要做的两件事是:
async
的方法。await
在您的示例中,您有一个线程被阻塞。假设有一个单线程上下文,并且线程在该上下文中被阻塞。您仍然不会遇到死锁,因为该Task.Delay
方法不会捕获其上下文。所以不会出现僵局。