'await' works, but calling task.Result hangs/deadlocks

前端 未结 5 1787
旧巷少年郎
旧巷少年郎 2020-11-21 23:56

I have the following four tests and the last one hangs when I run it. Why does this happen:

[Test]
public void CheckOnceResultTest()
{
    Assert.IsTrue(Check         


        
相关标签:
5条回答
  • 2020-11-22 00:15

    You can avoid deadlock adding ConfigureAwait(false) to this line:

    IRestResponse<DummyServiceStatus> response = await restResponse;
    

    =>

    IRestResponse<DummyServiceStatus> response = await restResponse.ConfigureAwait(false);
    

    I've described this pitfall in my blog post Pitfalls of async/await

    0 讨论(0)
  • 2020-11-22 00:28

    If you don't get any callbacks or the control hangs up, after calling the service/API async function, you have to configure Context to return a result on the same called context.

    Use TestAsync().ConfigureAwait(continueOnCapturedContext: false);

    You will be facing this issue only in web applications, but not in static void main.

    0 讨论(0)
  • 2020-11-22 00:35

    You're running into the standard deadlock situation that I describe on my blog and in an MSDN article: the async method is attempting to schedule its continuation onto a thread that is being blocked by the call to Result.

    In this case, your SynchronizationContext is the one used by NUnit to execute async void test methods. I would try using async Task test methods instead.

    0 讨论(0)
  • 2020-11-22 00:36

    Acquiring a value via an async method:

    var result = Task.Run(() => asyncGetValue()).Result;
    

    Syncronously calling an async method

    Task.Run( () => asyncMethod()).Wait();
    

    No deadlock issues will occur due to the use of Task.Run.

    0 讨论(0)
  • 2020-11-22 00:38

    You are blocking the UI by using Task.Result property. In MSDN Documentation they have clearly mentioned that,

    "The Result property is a blocking property. If you try to access it before its task is finished, the thread that's currently active is blocked until the task completes and the value is available. In most cases, you should access the value by using Await or await instead of accessing the property directly."

    The best solution for this scenario would be to remove both await & async from methods & use only Task where you're returning result. It won't mess your execution sequence.

    0 讨论(0)
提交回复
热议问题