c# - 不能使用扩展命令从同步调用异步?
问题描述
我发现我们在代码库中使用的一种扩展方法,用于从同步代码中调用异步方法并没有完全达到我的预期。代码遵循 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 代码
不可以。任何扩展方法都Task
在 的单个实例上运行Task
,并且该方法必须在代码具有.Task
一旦你的代码有了Task
,再改变方法的调用方式就太晚了。最好的解决方案是通过委托。或者只是完全删除该AsyncSafeWait
方法,然后开始清理。
推荐阅读
- python - 在 python 中使用 pyplot 绘制多个图
- c++ - 转换 std::vector
到 matlab setVariable 可用数组 - c# - 如何将 Google Cloud SQL 与 C# 连接起来
- mysql - 如果他在投票表中的条目最高,则从候选人表中选择姓名
- css - 使用 CSS flexbox 网格填充 API 数据
- javascript - Angular 单元测试:单击 DOM 后无法更改属性值
- c - 基于用户输入的决策
- c# - 如何插入json文件而不删除以前的数据?
- r - install_github 在 Windows 机器上失败
- hyperledger-fabric - 在 Hyperledger Fabric 中交换节点角色