如果首先提取任务,则异步任务死锁

问题描述 投票:1回答:1

我正在使用Microsoft的AsyncHelpersource)从同步上下文中调用异步方法。这很好用:

Result r = AsyncHelper.RunSync(async () => await SomeClass.SomeMethodAsync());

但是,如果我提取任务,然后尝试同步运行此提取的任务,则会遇到死锁。:

Task<Result> t = SomeClass.SomeMethodAsync();
Result r = AsyncHelper.RunSync(async () => await t);

为什么会发生这种情况,以及如何进行此操作?

c# async-await task task-parallel-library deadlock
1个回答
0
投票

AsyncHelper.RunSync使用thread pool hack来确保在没有上下文的情况下调用其委托,因此可以安全地进行阻塞(假设可以在线程池线程上安全地委托该委托)。在您的代码中,SomeMethodAsync在线程池线程上执行,因此任何await都不会capture a context

如何进行此操作?

嗯,您将使用第一个代码示例而不是第二个代码示例。

如果要具有一个表示要运行的某些代码的构造,则应使用诸如Func<Task<T>>的委托类型。例如:

Func<Task<Result>> func = () => SomeClass.SomeMethodAsync();
Result r = AsyncHelper.RunSync(func);

对于异步代码,Task<T>并不代表要运行的某些代码;它表示已经启动的一些代码。使用Func<Task<T>>代表要运行的某些代码。

© www.soinside.com 2019 - 2024. All rights reserved.