在我的asp.net应用程序中,我正在调用我添加到应用程序中的nuget包中的一种异步方法。现在,我有了一个同步方法,在其中需要调用添加的.dll的异步方法。为此,我调用了这些方法并检索了我使用的结果var value = myDllClient.MyMethod()。GetAwaiter()。GetResult();和var value = myDllClient.MyMethod()。Result ;,但是这些都不对我有用,但是线程进入了永无止境的进程。我什么也没收到所以我用var value = Task.Run(async()=>等待myDllClient.MyMethod())。Result;令人惊讶地工作正常。我不知道它如何运作?谁能帮助我了解这个谜?在此先感谢
因此,我调用了这些方法并检索了使用的结果
更好的解决方案是使用await
和allow the asynchrony to grow naturally through the code base。如果您执行have进行异步同步,则direct blocking like that may cause deadlocks。
await
captures a context by default,并且在您的情况下,await
内部的await
正在捕获MyMethod
,它存在于ASP.NET的ASP.NET request context版本中。然后,调用代码通过调用pre-Core / GetResult()
在该请求上下文中阻止线程。稍后,当Result
准备好继续时,它将await
的其余部分安排到该上下文。但是它永远不会运行,因为在该上下文中有一个线程正在等待MyMethod
完成。
MyMethod
不会死锁的原因是,Task.Run
使用线程池上下文而不是ASP.NET请求上下文。这是进行异步同步的MyMethod
方法。但是,"thread pool hack";如果可能,请更改代码以改为使用Task.Run
is not recommended on ASP.NET。
通过将调用包裹在Task.Run
中,您正在将该代码与ASP.NET的await
隔离开,因此您的代码不会死锁。