尝试在Visual Studio 2012中使用.net 4.0上的Microsoft.Bcl使用Async。结果未显示。
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;
}
答案 0 :(得分:1)
这是问题所在,与您使用.NET 4的事实无关:
Task.WaitAll(tasks, -1);
这将阻止tasks
中的所有内容完成。此时,您的UI线程无法再执行任何工作了......但已做更多工作,以便在ReceiveStringAsync
之后恢复await
内的代码表达。因此,在Task.WaitAll
完成之前,您的任务无法完成,在任务完成之前无法完成,并且您遇到了死锁。
这里的教训是从不在UI线程中使用阻止调用,例如Task.WaitAll
(或Task.Result
或Task.Wait()
)。
解决方案是同时使button3_Click
异步,因此await
可以Task<byte[]>
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());
}
。
ReceiveStringAsync
顺便说一句,Task<byte[]>
方法返回Task<string>
而不是{{1}} ... 真的奇怪