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

时间:2017-02-15 02:08:07

标签: c# wpf cefsharp

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

这是我的代码:

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来打印链接。在我的程序输出中,它打印所有链接,然后下载文件。问题是它只下载最后一个文件。我需要它等待并下载下一个文件。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

你的问题是

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));
  }

答案 1 :(得分:0)

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

因此,在await循环中使用foreach方法,您应该将Task.WhenAll()用于所有任务,如下例所示:

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()或不同的技术。

答案 2 :(得分:0)

您的代码应该始终是异步的,您不应该阻止异步代码。有关更多信息,请参阅@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));
}