await Task.WhenAll 看似完成,但它永远不会到达下一行代码
await Task.WhenAll seemingly completes, but it never reaches next line of code
我有一个简单的文件下载器,我从服务器上获取一些文件,然后显示一条消息,告知它是成功还是失败。这是代码:
public async Task GetFiles(IEnumerable<string> urlList)
{
//some variable declaring, setting etc.
await Task.WhenAll(urlList.Select(url => Task.Run(() => DownloadFile(url, dir, count++))).ToList());
//problem lies here, the WhenAll never completes
if (fileDownloadError)
{
Directory.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "downloads"));
MessageBox.Show("Fail");
return;
}
MessageBox.Show("Success");
}
internal async Task DownloadFile(string url, string dir, int count)
{
string filename = HelperClass.GetFilenameFromUrl(url);
long a = 0;
newList.Add(a);
using (var client = new WebClient())
{
TempDownload tp = new TempDownload()
{
id = count
};
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) => ProgressChanged(sender, e, tp));
client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
await client.DownloadFileTaskAsync(url, string.Concat(dir, "\", filename));
}
}
ProgressBar
我在 DownloadProgressChanged
事件中更改为 100%,文件已正确下载,但 WhenAll
之后的代码从未执行,即它从未命中if (fileDownloadError)
上的断点,未显示 MessageBox 等。我在这里遗漏了什么吗?
由于死锁,断点永远不会命中 if 语句。将 ConfigureAwait(false) 添加到所有等待。前-
await Task.WhenAll(urlList.Select(url => Task.Run(() => DownloadFile(url, dir, count++))).ToList()).ConfigureAwait(false);
还有
await client.DownloadFileTaskAsync(url, string.Concat(dir, "\", filename)).ConfigureAwait(false);
解决这个问题的另一个选择是,不在 UI 线程上使用 Wait 或 Result。使用异步等待
ex-
private async void button1_Click(object sender, EventArgs e)
{
await GetFiles();
}
详情,
https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
我有一个简单的文件下载器,我从服务器上获取一些文件,然后显示一条消息,告知它是成功还是失败。这是代码:
public async Task GetFiles(IEnumerable<string> urlList)
{
//some variable declaring, setting etc.
await Task.WhenAll(urlList.Select(url => Task.Run(() => DownloadFile(url, dir, count++))).ToList());
//problem lies here, the WhenAll never completes
if (fileDownloadError)
{
Directory.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "downloads"));
MessageBox.Show("Fail");
return;
}
MessageBox.Show("Success");
}
internal async Task DownloadFile(string url, string dir, int count)
{
string filename = HelperClass.GetFilenameFromUrl(url);
long a = 0;
newList.Add(a);
using (var client = new WebClient())
{
TempDownload tp = new TempDownload()
{
id = count
};
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler((sender, e) => ProgressChanged(sender, e, tp));
client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
await client.DownloadFileTaskAsync(url, string.Concat(dir, "\", filename));
}
}
ProgressBar
我在 DownloadProgressChanged
事件中更改为 100%,文件已正确下载,但 WhenAll
之后的代码从未执行,即它从未命中if (fileDownloadError)
上的断点,未显示 MessageBox 等。我在这里遗漏了什么吗?
由于死锁,断点永远不会命中 if 语句。将 ConfigureAwait(false) 添加到所有等待。前-
await Task.WhenAll(urlList.Select(url => Task.Run(() => DownloadFile(url, dir, count++))).ToList()).ConfigureAwait(false);
还有
await client.DownloadFileTaskAsync(url, string.Concat(dir, "\", filename)).ConfigureAwait(false);
解决这个问题的另一个选择是,不在 UI 线程上使用 Wait 或 Result。使用异步等待
ex-
private async void button1_Click(object sender, EventArgs e)
{
await GetFiles();
}
详情,
https://msdn.microsoft.com/en-us/magazine/gg598924.aspx
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html