I have a good understanding of Task and the async/await pattern but recently someone fixed a deadlock that he said was caused by :
public async Task<HttpResponseMessage> GetHttpResponse()
{
using (var client = new HttpClient())
{
return await client.SendAsync(new HttpRequestMessage()).ConfigureAwait(false);
}
}
He says that he fixed it with some kind of Task.Factory.StartNew
pattern.
public HttpResponseMessage GetHttpResponse()
{
using (var client = new HttpClient())
{
return Task.Factory.StartNew(() => client.SendAsync(new HttpRequestMessage()).Result).Result;
}
}
First thing is that troubles is me is why would he change the return statement to be an HttpResponseMessage
as opposed to a Task<HttpResponseMessage>
.
My second question, is why would this code solve a deadlock bug. From my understanding, the fact that he calls a .Result
forces the GetHttpResponse
Thread to wait (and freeze) until the client.SendAsync
completes.
Can anyone try to explain me how this code affects any TaskScheduler
and SynchronizationContext
.
Thank you for your help.
EDIT : Here is the caller method to provide more context to the problem
public IWebRequestResult ExecuteQuery(ITwitterQuery twitterQuery, ITwitterClientHandler handler = null)
{
HttpResponseMessage httpResponseMessage = null;
try
{
httpResponseMessage = _httpClientWebHelper.GetHttpResponse(twitterQuery, handler).Result;
var result = GetWebResultFromResponse(twitterQuery.QueryURL, httpResponseMessage);
if (!result.IsSuccessStatusCode)
{
throw _exceptionHandler.TryLogFailedWebRequestResult(result);
}
var stream = result.ResultStream;
if (stream != null)
{
var responseReader = new StreamReader(stream);
result.Response = responseReader.ReadLine();
}
return result;
}
// ...