@ mrinal-kamboj @ panagiotis-kanavos @shay
Thank you all for your help. As already mentioned, I started reading Async in C# 5.0 from Alex Davies .
What i found
In chapter 8: Which thread runs my code, it mentions our case, and I think I found an interesting solution there:
You can work around the deadlock issue by going to the thread pool before running asynchronous code so that the captured SynchronizationContext is a thread pool and not a user interface thread.
var result = Task.Run(() => MethodAsync()).Result;
By Task.Run , it actually causes the asynchronous call to SynchronizationContext be SynchronizationContext ThreadPool (which makes sense). However, it also ensures that MethodAsync code MethodAsync not start and does not return to the main thread.
My decision
Given this, I changed my code as follows:
public HttpResponseMessage GetHttpResponse() { using (var client = GetHttpClient()) { return TaskEx.Run(() => client.SendAsync(new HttpRequestMessage())).Result; } }
This code works correctly for Console, WPF, WinRT, and ASP.NET. I will conduct further testing and update this post.
Questions
- Do you think this new code makes sense?
- Do you think this will prevent any potential impasse?
Note
In this book, I found out that .ConfigureAwait(false) only prevents the callback to call the SynchronizationContext.Post() method, which must be run on the caller's thread. In order to determine the thread to which the callback should be executed, it is important that the SynchronizationContext checks if the thread with which it is associated is associated. If so, then he chooses a different thread.
From my understanding, this means that the callback can be launched in any thread (UI-Thread or ThreadPool). Therefore, it does not guarantee non-execution in the UI-Thread, but makes it very unlikely.
NOTE (2)
It is interesting to note that the following code does not work:
public async Task<HttpResponseMessage> GetHttpResponse() { using (var client = GetHttpClient()) { return await TaskEx.Run(() => client.SendAsync(new HttpRequestMessage()));
When I tried to get this code, I meant that .Result can be used outside the ThreadPool area expected by .Result . To some extent, this makes sense to me, but if someone wants to comment on this, he will be happy :)