C# 无法使用扩展命令从同步调用异步?
我发现我们在代码库中用来从同步代码调用异步方法的扩展方法并没有完全达到我的预期。代码遵循MSDN的指导原则: 但是,由于这是一个扩展方法,异步调用将启动,因此在将C# 无法使用扩展命令从同步调用异步?,c#,.net,asynchronous,task,C#,.net,Asynchronous,Task,我发现我们在代码库中用来从同步代码调用异步方法的扩展方法并没有完全达到我的预期。代码遵循MSDN的指导原则: 但是,由于这是一个扩展方法,异步调用将启动,因此在将任务交给扩展方法之前捕获当前上下文。这在许多同步情况下会导致问题,最明显的是在UI线程上,它会导致死锁。从本质上讲,扩展方法没有比.Result更有用,因为同样的原因和更多的原因,这是一种糟糕的做法 我的问题是:有没有办法结束这个难看的反异步任务。运行代码,这样我就不必复制粘贴任务。运行(async()=>retVal=Wait The
任务
交给扩展方法之前捕获当前上下文。这在许多同步情况下会导致问题,最明显的是在UI线程上,它会导致死锁。从本质上讲,扩展方法没有比.Result
更有用,因为同样的原因和更多的原因,这是一种糟糕的做法
我的问题是:有没有办法结束这个难看的反异步任务。运行代码,这样我就不必复制粘贴任务。运行(async()=>retVal=Wait TheRealAsyncCall(…).Wait()代码>无处不在
谢谢大家!
有没有办法结束这个丑陋的反异步任务。运行代码
否。任何任务
扩展方法都是在任务
的单个实例上运行的,并且该方法必须在代码具有任务
时已被调用
一旦你的代码有了一个任务
,改变调用方法的方式就太晚了。最好的解决方案是传递一个委托。或者完全删除AsyncSafeWait
方法,然后开始清理
有没有办法结束这个丑陋的反异步任务。运行代码
否。任何任务
扩展方法都是在任务
的单个实例上运行的,并且该方法必须在代码具有任务
时已被调用
一旦你的代码有了一个任务
,改变调用方法的方式就太晚了。最好的解决方案是传递一个委托。或者干脆完全删除AsyncSafeWait
方法,然后开始清理。“这会在许多同步情况下导致问题”——如果没有具体问题,问题就太广泛了。但是,您是否尝试过在task.Run()
委托中简单地使用await task.ConfigureAwait(false)
?如果您可以改进该问题,使其包含一个很好的示例,演示要解决的单个特定问题,这将有助于使其适合堆栈溢出。是的。使用async方法包装它,并使其他方法也异步;)“这在许多同步情况下会导致问题”——如果没有具体问题,问题就太广泛了。但是,您是否尝试过在task.Run()
委托中简单地使用await task.ConfigureAwait(false)
?如果您可以改进该问题,使其包含一个很好的示例,演示要解决的单个特定问题,这将有助于使其适合堆栈溢出。是的。使用async方法包装它,并使其他方法也异步;)“或者干脆完全删除AsyncSafeWait
方法,然后开始清理。”-我知道你知道这个Stephen,但我只想向OP强调,这确实是最理想的方式。人们不断发现这种方法,并认为“微软做到了,所以它一定没问题。”但这是一种毒药。@GabrielLuci:我不知道微软有任何AsyncSafeWait
方法会这样做;这种方法从根本上被打破了。引用的文章在任务中运行异步代码。运行
,因此基于该文章的方法应采用委托参数,而不是任务
。但是,是的,我多次看到同样的问题。对不起,我没有点击链接:)我以为这是对的引用。“或者干脆完全删除AsyncSafeWait
方法,然后开始清理。”-我知道你知道这个Stephen,但我只想向OP强调,这确实是最理想的方式。人们不断发现这种方法,并认为“微软做到了,所以它一定没问题。”但这是一种毒药。@GabrielLuci:我不知道微软有任何AsyncSafeWait
方法会这样做;这种方法从根本上被打破了。引用的文章在任务中运行异步代码。运行
,因此基于该文章的方法应采用委托参数,而不是任务
。但是,是的,同样的问题我已经见过好几次了。对不起,我没有点击链接:)我以为这是对的参考。
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();