I\'m using the HttpClient to post data to a remote service in a .NET 4.0 project. I\'m not concerned with this operation blocking, so I figured I could skip ContinueWith or
Capturing the result of a task blocks the current thread. There is no point in using a async version of a method in this case. Post()
and PostAsync().Result
will both block.
If you want to make use of concurrency, you should write it as such:
async Task PostContent()
{
var client = new HttpClient();
Task t = await client.PostAsync("http://someservice/", someContent);
//code after this line will execute when the PostAsync completes.
return t;
}
Since PostContent()
itself returns a Task, the method calling it should also await.
async void ProcessResult()
{
var result = await PostContent();
//Do work with the result when the result is ready
}
For instance, if you call ProcessResult()
in a button click handler, you see that the UI is still responsive, other controls still function.
In Windows, all I/O is asynchronous. Synchronous APIs are just a convenient abstraction.
So, when you use HttpWebRequest.GetResponse
, what actually happens is the I/O is started (asynchronously), and the calling thread (synchronously) blocks, waiting for it to complete.
Similarly, when you use HttpClient.PostAsync(..).Result
, the I/O is started (asynchronously), and the calling thread (synchronously) blocks, waiting for it to complete.
I usually recommend people use await
rather than Task.Result
or Task.Wait
for the following reasons:
Task
that is the result of an async
method, you can easily get into a deadlock situation.Task.Result
and Task.Wait
wrap any exceptions in an AggregateException
(because those APIs are holdovers from the TPL). So error handling is more complex.However, if you're aware of these limitations, there are some situations where blocking on a Task
can be useful (e.g., in a Console application's Main
).