gpt4 book ai didi

c# - Task.Run vs Task.Factory.StartNew - 没有发生预期的死锁

转载 作者:行者123 更新时间:2023-12-03 21:54:01 27 4
gpt4 key购买 nike

我阅读了 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 之后等待任务也不会抛出,因为它是 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.Factory.StartNew当与异步委托(delegate)一起使用时,返回一个嵌套任务:Task<Task> .您正在将此嵌套任务分配给类型为 Task 的变量。 ,这是允许的,因为类 Task<TResult>派生自类 Task .然后发生的事情是您失去了对内部任务的引用,因此您无法等待它。当你await this.backgroundTask您正在等待外部 Task<Task> ,但无法得到等待操作的结果,即 Task ,内Task , 和 await它。内心的任务已经变成了即发即弃的任务。

关于c# - Task.Run vs Task.Factory.StartNew - 没有发生预期的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62145692/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com