An async/await example that causes a deadlock

后端 未结 5 1923
暗喜
暗喜 2020-11-21 13:32

I came across some best practices for asynchronous programming using c#\'s async/await keywords (I\'m new to c# 5.0).

One of the advices gi

5条回答
  •  你的背包
    2020-11-21 14:15

    • Fact 1: GetDataAsync().Result; will run when the task returned by GetDataAsync() completes, in the meantime it blocks the UI thread
    • Fact 2: The continuation of the await (return result.ToString()) is queued to the UI thread for execution
    • Fact 3: The task returned by GetDataAsync() will complete when its queued continuation is run
    • Fact 4: The queued continuation is never run, because the UI thread is blocked (Fact 1)

    Deadlock!

    The deadlock can be broken by provided alternatives to avoid Fact 1 or Fact 2.

    • Avoid 1,4. Instead of blocking the UI thread, use var data = await GetDataAsync(), which allows the UI thread to keep running
    • Avoid 2,3. Queue the continuation of the await to a different thread that is not blocked, e.g. use var data = Task.Run(GetDataAsync).Result, which will post the continuation to the sync context of a threadpool thread. This allows the task returned by GetDataAsync() to complete.

    This is explained really well in an article by Stephen Toub, about half way down where he uses the example of DelayAsync().

提交回复
热议问题