【发布时间】:2020-01-20 23:05:44
【问题描述】:
我发现我们一直在代码库中使用的一种扩展方法从同步代码中调用异步方法并没有完全达到我的预期。代码遵循 MSDN 上的指南:https://docs.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development
public static T AsyncSafeWait<T>(this Task<T> task)
{
T retVal = default;
Task.Run(async () => retVal = await task).Wait();
return retVal;
}
这允许简单直观的使用:
var response = PostAsync(...).AsyncSafeAwait();
但是,由于这是一种扩展方法,因此会启动异步调用,因此在将 Task 交给扩展方法之前会捕获当前上下文。这在许多同步情况下会导致问题,最明显的是在导致死锁的 UI 线程上。从本质上讲,扩展方法并不比 .Result 有用,出于同样的原因等等,这是一种不好的做法。
我的问题是:有什么办法可以结束这个丑陋的去异步 Task.Run 代码,这样我就不必到处复制粘贴 Task.Run(async () => retVal = await TheRealAsyncCall(...)).Wait(); 了吗?
谢谢!
【问题讨论】:
-
“这会导致许多同步情况下的问题” -- 如果没有特定 问题,问题就太宽泛了。但是,您是否尝试过在
Task.Run()委托中简单地使用await task.ConfigureAwait(false)?如果您可以改进问题,使其包含一个很好的 minimal reproducible example 来展示要解决的单个特定问题,这将有助于使其适用于 Stack Overflow。 -
是的。用异步方法包装它,并使其他方法也异步;)
标签: c# .net asynchronous task