等待在循环 wpf 中执行下一个代码



我有一个下载链接列表,我正在使用cefsharp下载。我无法使用网络客户端下载文件,用户必须登录。

这是我的代码:

foreach (var lnk in collection) {
Console.WriteLine(lnk);
await TestAsync(lnk);
}
private  Task TestAsync(string lnk) {
return Task.Run(() => TaskToDo(lnk));
}
private async void TaskToDo(string lnk) {
await wb.GetBrowser().MainFrame.EvaluateScriptAsync(String.Format("window.location.href = '{0}'", lnk));
}

在我的循环中,我有一个打印链接Console.WriteLine。在我的程序输出中,它会打印所有链接,然后下载一个文件。问题是它只下载最后一个文件。我需要它等待并下载下一个文件。

我该如何解决这个问题?

你的问题是

async void

这不会被调用者阻止,这就是为什么你在不需要的时候执行 Task.Run 的原因。

foreach (var item in collection)
{
Console.WriteLine(lnk);
await TestAsync(lnk);
}
private  Task TestAsync(string lnk)
{
return TaskToDo(lnk);
}
private Task TaskToDo(string lnk)
{
return wb.GetBrowser().MainFrame.EvaluateScriptAsync(String.Format("window.location.href = '{0}'", lnk));
}

您没有正确使用 await 关键字。在这种情况下,您告诉每次迭代循环时都希望等待。最好从TestAsync(lnk)返回Task并放在任务列表中。

因此,您应该对所有任务使用Task.WhenAll(),而不是foreach循环中的方法await,如以下示例所示:

List<Task> taskList = new List<Task>();
foreach (var lnk in collection)
{
Console.WriteLine(lnk);
var task = TestAsync(lnk);
taskList.Add(task);
}
await Task.WhenAll(taskList.ToArray());

关于:

问题是它只下载最后一个文件。我需要它等待 并下载下一个文件。 我该如何解决这个问题?

我怀疑您无法异步下载带有window.lotion.href的文件,因为您要在上一个操作完成之前按顺序更改窗口的位置!

基本上,当您正在下载 LINK1 另一个任务时,示例 LINK3 将开始下载并且 LINK1 将停止。这就是您只下载一个文件的原因。尝试使用window.open()或不同的一些不同的技术。

你的代码应该一直都是异步的,你不应该阻止异步代码。有关详细信息,请参阅 @Stephen Cleary 的 MSDN 文章:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

这里的问题是您的TestAsync方法启动一个新的Task,它将在后台线程上执行,并在任务实际完成之前立即返回。

您应该使TestAsync方法async并将TaskToDo方法的返回类型更改为Task以便能够等待此方法:

foreach (var lnk in collection) {
Console.WriteLine(lnk);
await TestAsync(lnk);
}
private async Task TestAsync(string lnk)
{
await TaskToDo(lnk);
}
private async Task TaskToDo(string lnk)
{
await wb.GetBrowser().MainFrame.EvaluateScriptAsync(String.Format("window.location.href = '{0}'", lnk));
}

最新更新