这是.NET 4.5的WhenAll的正确.NET 4实现吗?

我正在使用SignalR。 Hub上的function通常返回一个Task。 我现在有一个函数可以添加一组连接。 我想返回一个代表所有这些任务的Task。

我找到了一个完美的function:Task.WhenAll。 然而,这是.NET 4.5中的一项新function,我仍然坚持使用.NET 4。

因此,我决定编写自己的版本,直到我们可以转到.NET 4.5。 因为在涉及multithreading时经常有一些警告(例如线程池的东西),我不确定我的实现是否正确:

public static Task WhenAll(IEnumerable tasks) { return Task.Factory.StartNew(() => Task.WaitAll(tasks.ToArray())); } 

在function上,我认为它可行,但是我不会为新任务获得额外的阻塞线程吗? 或者这是不可避免的?

编辑:以下是我将如何与SignalR一起使用:

 public static Task Add(this IGroupManager groupManager, string connectionId, IEnumerable groups) { return WhenAll(groups.Select(group => groupManager.Add(connectionId, group))); } 

你的解决方案可以正常工作,但你是正确的,它会一直阻塞一个线程。

我认为在.Net 4.0上有效实现WhenAll()的最简单方法是使用ContinueWhenAll() 。 它在集合中的所有Task完成后执行操作,并返回表示该操作的Task 。 由于我们只想要那个Task ,我们不需要动作,传递一个空的lambda会起作用:

 public static Task WhenAll(IEnumerable tasks) { return Task.Factory.ContinueWhenAll(tasks.ToArray(), _ => {}); } 

虽然你的目标是.Net 4.0,如果你可以使用VS2012,那么更简单/更好的选择(恕我直言)是使用NuGet来安装异步目标包然后你可以使用WhenAll( TaskEx.WhenAll在这种情况下,因为它无法修改4.0框架中的任务。

作为一个重要的额外奖励,您可以在.Net 4.0代码中使用async / await 🙂