【发布时间】:2020-09-20 13:10:37
【问题描述】:
我了解了 Task.Run 和 Task.Factory.StartNew 的区别。
Task.Run(() => {});
应该等价于
Task.Factory.StartNew(() => {}, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
但在我的代码中,我预计由于 Task.Factory.StartNew 不会发生死锁:
private Task backgroundTask;
private async Task DoSomethingAsync()
{
// this should deadlock
await this.backgroundTask.ConfigureAwait(false);
throw new Exception();
}
private async Task Test()
{
this.backgroundTask = Task.Factory.StartNew(async () =>
{
await this.DoSomethingAsync().ConfigureAwait(false);
}, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
// just wait here for testing/debugging
await Task.Delay(10000).ConfigureAwait(false);
// if no deadlock, this should throw
await this.backgroundTask.ConfigureAwait(false);
}
但这不是死锁。 DoSomethingAsync 中的异常被抛出但从未被捕获。 在Task.Delay之后等待Task也不会抛出,因为它是RanToCompletion。
当使用 Task.Run 时,它会像预期的那样死锁:
private Task backgroundTask;
private async Task DoSomethingAsync()
{
// this is deadlocking
await this.backgroundTask.ConfigureAwait(false);
throw new Exception();
}
private async Task Test()
{
this.backgroundTask= Task.Run(async () =>
{
await this.DoSomethingAsync().ConfigureAwait(false);
});
// just wait here for testing/debugging
await Task.Delay(10000).ConfigureAwait(false);
// never reached because of deadlock
await this.backgroundTask.ConfigureAwait(false);
}
谁能解释这种行为?
【问题讨论】:
-
看过这篇文章了吗? Task.Run vs Task.Factory.StartNew
标签: c# async-await task deadlock