Trying to use Async using Microsoft.Bcl on .net 4.0 in Visual Studio 2012. Results does not show up.
private void button3_Click(object sender, EventArgs e)
{
byte[] resultBytes;// = ReceiveStringAsync().Result;
Task<byte[]>[] tasks = new Task<byte[]>[1];
tasks[0] = ReceiveStringAsync();
Task.WaitAll(tasks, -1);
resultBytes = tasks[0].Result;
MessageBox.Show("Async Mode called in sync - " + data.Length.ToString());
}
public async Task<byte[]> ReceiveStringAsync()
{
string strURL = @"https://testurl.com";
WebClient client = new WebClient();
byte[] data = await client.DownloadDataTaskAsync(strURL).ConfigureAwait(true);
return data;
}
This is the problem, which has nothing to do with the fact that you're using .NET 4:
Task.WaitAll(tasks, -1);
That will block until everything in tasks
completes. At that point, your UI thread can't do any more work... but it has to do more work in order to resume the code within ReceiveStringAsync
after the await
expression. So your task can't complete until Task.WaitAll
has completed, which can't complete until the task has completed, and you have a deadlock.
The lesson here is never to use blocking calls like Task.WaitAll
(or Task.Result
or Task.Wait()
) within the UI thread.
The solution is to make button3_Click
async as well, so you can await
the Task<byte[]>
returned by ReceiveStringAsync
.
private async void button3_Click(object sender, EventArgs e)
{
byte[] resultBytes = await ReceiveStringAsync();
// Not clear what data is here, but that's a different matter...
MessageBox.Show("Async Mode called in sync - " + data.Length.ToString());
}
As an aside, it's really odd for a ReceiveStringAsync
method to return a Task<byte[]>
instead of a Task<string>
...
See more on this question at Stackoverflow