Why ThreadPool decides to use the exact context thread which called Task.Wait?
There is the question. For some reasons I do not see a comment button neither for the question nor for any of its answers. So, I am asking a related question in a separate thread.
In the linked question there is an answer which points to the blog. According to this blog the following statement holds.
There is the code piece:
// My "library" method.
public static async Task<JObject> GetJsonAsync(Uri uri)
{
// (real-world code shouldn't use HttpClient in a using block; this is just example code)
using (var client = new HttpClient())
{
var jsonString = await client.GetStringAsync(uri);
return JObject.Parse(jsonString);
}
}
// My "top-level" method.
public void Button1_Click(...)
{
var jsonTask = GetJsonAsync(...);
textBox1.Text = jsonTask.Result;
}
And there is the deadlock occurrence explanation:
- The top-level method calls
GetJsonAsync(within the UI/ASP.NET context).GetJsonAsyncstarts the REST request by callingHttpClient.GetStringAsync(still within the context).GetStringAsyncreturns an uncompletedTask, indicating the REST request is not complete.GetJsonAsyncawaits theTaskreturned byGetStringAsync. The context is captured and will be used to continue running theGetJsonAsyncmethod later.GetJsonAsyncreturns an uncompleted Task, indicating that theGetJsonAsyncmethod is not complete.- The top-level method synchronously blocks on the Task returned by
GetJsonAsync. This blocks the context thread.- … Eventually, the REST request will complete. This completes the
Taskthat was returned byGetStringAsync.- The continuation for
GetJsonAsyncis now ready to run, and it waits for the context to be available so it can execute in the context.- Deadlock. The top-level method is blocking the context thread, waiting for
GetJsonAsyncto complete, andGetJsonAsyncis waiting for the context to be free so it can complete.
And my question is particularly about the step 7. Why does the ThreadPool decides to take a blocked thread and wait while it will unblock to ask that thread to run the code? Why not just take any other thread?