首页 > 解决方案 > 不能使用扩展命令从同步调用异步?

问题描述

我发现我们在代码库中使用的一种扩展方法,用于从同步代码中调用异步方法并没有完全达到我的预期。代码遵循 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();到处复制粘贴了?

谢谢!

标签: c#.netasynchronoustask

解决方案


有什么办法可以结束这个丑陋的去异步 Task.Run 代码

不可以。任何扩展方法Task在 的单个实例上运行Task,并且该方法必须在代码具有.Task

一旦你的代码有了Task,再改变方法的调用方式就太晚了。最好的解决方案是通过委托。或者只是完全删除该AsyncSafeWait方法,然后开始清理。


推荐阅读