【问题标题】:Task.WaitAny to accept Task<T> instead of Task [ ]Task.WaitAny 接受 Task<T> 而不是 Task [ ]
【发布时间】:2015-10-07 18:36:41
【问题描述】:

我有一组标记为执行的通用任务。当任务完成时(使用Task.WaitAny),我将其添加到ObservableCollection

但是,问题出在Task.WaitAny(...) 行,它说从 Task[] 到 Task[] 的协变数组转换会导致写入操作时出现运行时异常。

我相当了解此异常的含义以及它在此阶段抱怨的原因。

问题:是否有Task.WaitAny()的通用版本,可以将Task&lt;T&gt;作为参数而不是Task[]

提前致谢。

【问题讨论】:

  • @chuex 这些问题的答案已经过时了。现在有更好的方法。
  • @Nair:为什么要从可观察集合中的任务开始?当然它们不是数据绑定的......
  • @StephenCleary,此代码只是演示问题的剥离版本。现在回答您的问题,单个任务的结果必须绑定到 WPF 中的控件,并且意图是具有响应式 UI。
  • @Nair:你不能绑定到 Task&lt;T&gt;.Result 并拥有一个响应式 UI。

标签: c# multithreading generics task-parallel-library task


【解决方案1】:

有一个通用的Task.WhenAny

public static Task<Task<TResult>> WhenAny<TResult>(IEnumerable<Task<TResult>> tasks);
public static Task<Task<TResult>> WhenAny<TResult>(params Task<TResult>[] tasks);

await获取已完成的任务。

【讨论】:

  • 感谢您的支持。抱歉,我使用的是 .NET 4。
  • @Nair 如果您在 VS 2012 或更高版本中使用 .NET 4,您可以从 nuget 获取 Microsoft.Bcl.Async 包并使用 TaskEx.WhenAny。
【解决方案2】:

您可以使用Task.WhenAny,在您的情况下,它甚至可以像这样简化您的代码

var result = new ObservableCollection<LenderScoreCard>();
var parallelScoreList = parallelScore.ToList();
while (parallelScoreList.Count != 0)
{
    var completedTask = Task.WhenAny(parallelScoreList).Result;
    result.Add(completedTask.Result);
    parallelScoreList.Remove(completedTask);
}

【讨论】:

  • 感谢您的支持。抱歉,我使用的是 .NET 4。
  • @Nair: Np,然后忽略警告 - Task.WaitAny 无论如何都不会修改传递的数组。
猜你喜欢
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
相关资源
最近更新 更多