Reputation: 153
I am facing problem in calling HttpClient class and async call. I call the function List() from page_load. The calls return from the line HttpResponseMessage response = await client.GetAsync(str); and never comes back to finish it.
I don't understand what mistake I am doing. Following is my code:
protected void Page_Load(object sender, EventArgs e)
{
Task<string> s= List(product);
}
protected async Task<string> List(string ProductType)
{
string str = "http://xx.xx.com/wiki/api.php";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", "username", "password"))));
HttpResponseMessage response = await client.GetAsync(str);
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
}
return content;
}
It never executes following lines.
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
Please help. Thanks in advance.
Upvotes: 1
Views: 3342
Reputation: 456322
You never show what happens to the task in Page_Load
, but given your symptoms and the fact that Page_Load
is not async
, I'm betting that you're calling Result
or Wait
instead of await
ing it.
When you do that, you cause a deadlock. The link to my blog explains this in detail, but the gist is that await
will capture and restore the current "context". In ASP.NET, this is a request context, and the request context only allows one thread executing in it at a time. So, if you call Result
or Wait
(while you're in the request context), you'll block a thread in that request context until the Task<string>
completes. Meanwhile, when the HttpClient
gets its response, it tries to resume after the await client.GetAsync(str)
. But the request context will only allow one thread in at a time, and that thread is blocked waiting for the Task
to complete. Since List
cannot complete because the context is busy, you have a deadlock.
To prevent deadlocks, follow these two best practices (from my recent MSDN article):
async
all the way. That is, use await
instead of Result
or Wait
.ConfigureContext(false)
in your "library" code, i.e., every await
in List
should actually be await ... .ConfigureAwait(false);
Upvotes: 1