我有一个下载链接列表,我正在使用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));
}