我正在尝试使用任务一次下载多个站点的方式从多个URL下载页面源。问题是我想在每个任务完成时保持UI更新。当我尝试等待所有任务时,它将停止更新UI,直到所有任务完成为止。这是我正在使用的当前代码。
编辑:我假设我因投票解释不充分而被否决。我想一个更好的方法是为什么在Task.WaitAll之前不运行continueWith。我希望用户界面在下载源的每次完成时都进行更新。完成所有操作后,将更新列表框,以使用户知道一切已完成。
private void btnGetPages_Click(object sender, EventArgs e)
{
for (int i = 1; i < 11; i++)
{
string url = $"http://someURL/page-{i}.html";
listBoxStatus.Items.Add($"Downloading source from {url}...");
Task t = new Task(() =>
{
DownloadSource(url);
});
t.ContinueWith(prevTask => listBoxStatus.Items.Add($"Finished Downloading {url} source..."), TaskScheduler.FromCurrentSynchronizationContext());
tasks.Add(t);
t.Start();
}
Task.WaitAll(tasks.ToArray());
listBoxStatus.Items.Add("All Source files have completed...");
}
private void DownloadSource(string url)
{
var web = new HtmlWeb();
var doc = web.Load(url);
pageSource += doc.Text;
}
答案 0 :(得分:1)
您确实应该使用基于HttpClient
的异步下载方法,而不是所显示的同步方法。缺少这一点,我将使用这一点:
private async Task DownloadSourceAsync(string url)
{
await Task.Run(() => DownloadSource(url));
listBoxStatus.Items.Add($"Finished Downloading {url} source...");
}
然后,您可以使btnGetPages_Click
方法如下:
private async void btnGetPages_Click(object sender, EventArgs e)
{
var tasks = new List<Task>();
for (int i = 1; i < 11; i++)
{
string url = $"http://someURL/page-{i}.html";
listBoxStatus.Items.Add($"Downloading source from {url}...");
tasks.Add(DownloadSourceAsync(url));
}
Task.WaitAll(tasks.ToArray());
listBoxStatus.Items.Add("All Source files have completed...");
}