INTERNET APPLICATION DEVELOPMENT
MID MARKET ERP DEVELOPMENT
by Jacky Xu
I encountered a Dead Lock while working on a project to extract data from Intacct through a Web API. I tried HttpClient.SendAsync as I did not want to block the web page once I called it to retrieve data from the Web API. First, I created a test project to ensure everything ran accordingly before releasing this change. It didn't work the way I planned. After more research, I finally resolved the issue.
What causes the Dead Lock when using the Async Method?
I experienced two causes to this issue: through a Windows UI context, and through ASP.NET when requesting context. Turns out, my error occurred when I called Method A through the Windows UI event or through ASP.NET MVC and also by the controller’s “Get” function.
When you call any Async Method with Method A (e.g. HttpClient.SendAsync), you also need to call HttpResponseMessage.Content.ReadAsStringAsync() and wait to receive the uncompleted Task notification. Once you call the ReadAsStringAsync, the context is captured and is used to continue running Method A later. Now, when using the Windows UI event or controller’s “Get” function, the sync blocks the Task returned by ReadAsStringAsync and blocks the context thread. After the Task is complete (returned by ReadAsStringAsync), Method A runs and waits for the context thread to continue in the context. The Dead Lock occurs when Windows UI events or ASP.NET MVC controller’s “Get” function are waiting for Method A to complete, and Method A is not executing until the context thread is free.
How to avoid a Dead Lock.
First, when using the Async Method add: .ConfigurationAwait(false)
Here is an example of the original code:
Now, change your code like this to avoid the Dead Lock:
Do not sync the Task. Instead, add Async to all of the called methods.
Here is an example of original code:
Now, change your code to avoid the Dead Lock:
I hope you find this information helpful if you are ever faced with this situation.