GetAwaiter().GetResult() 和 .Result 都不适合我,但 Task.Run(await ()=> nameOfMethodTobeCalled()).Result 有效。我没听懂?

Neither GetAwaiter().GetResult() nor .Result worked for me but Task.Run(await ()=> nameOfMethodTobeCalled()).Result working. I didn't understand?

在我的 asp.net 应用程序中,我调用了我添加到我的应用程序中的一个 nuget 包的一些异步方法。现在我有一个同步方法,我需要在其中调用我添加的 .dll 的异步方法。因此,为此我调用了那些方法并检索了我使用的结果

var value = myDllClient.MyMethod().GetAwaiter().GetResult();和
var value = myDllClient.MyMethod().Result;,

但是 none 这些对我有用,但是线程进入了永无止境的过程。我从来没有收到任何东西 所以我用了

var value = Task.Run(async ()=> await myDllClient.MyMethod()).Result;

出奇地工作正常。 我不知道它是如何工作的? 谁能帮我解开这个奥秘?

提前致谢

通过将您的调用包装在 Task.Run 中,您将该代码与 ASP.NET 的 SynchronizationContext 隔离开来,因此您的代码不会死锁。

So for that I called those method and to retrieve result I used

更好的解决方案是使用 awaitallow the asynchrony to grow naturally through the code base. If you do have to do sync-over-async, then direct blocking like that may cause deadlocks

await captures a context by default, and in your case the await inside of MyMethod is capturing an ASP.NET request context, which existed on pre-Core 个版本 ASP.NET。然后,调用代码通过调用 GetResult()/Result 阻塞该请求上下文中的线程。稍后,当 await 准备好继续时,它将 MyMethod 的其余部分安排到该上下文。但它永远不会 运行 因为在那个上下文中有一个线程被阻塞等待 MyMethod 完成。

Task.Run 没有死锁的原因是 MyMethod 使用线程池上下文而不是 ASP.NET 请求上下文。这是"thread pool hack" approach to doing sync-over-async. However, Task.Run is not recommended on ASP.NET;如果可能,将代码更改为使用 await