简体   繁体   English

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

[英]Is this a correct .NET 4 implementation for .NET 4.5's WhenAll?

I am using SignalR. 我正在使用SignalR。 The function on the Hub often return a Task. Hub上的功能通常返回一个Task。 I now have a function that will add a connection to a bunch of groups. 我现在有一个函数可以添加一组连接。 I would like to return a Task that represents all of these Tasks. 我想返回一个代表所有这些任务的任务。

I found a perfect function for that: Task.WhenAll. 我发现了一个完美的功能:Task.WhenAll。 However this is a new function in .NET 4.5 and I am still stuck on .NET 4. 然而,这是.NET 4.5中的一项新功能,我仍然坚持使用.NET 4。

Hence I decided to write my own version of it until we can move to .NET 4.5. 因此,我决定编写自己的版本,直到我们可以转到.NET 4.5。 Because there are often some caveats when it comes to multithreading (eg thread pool stuff), I am not sure if my implementation is correct: 因为在涉及多线程时经常有一些警告(例如线程池的东西),我不确定我的实现是否正确:

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

Functionally, it works I think, but don't I get an extra blocked thread for the new Task? 在功能上,我认为它可行,但是我不会为新任务获得额外的阻塞线程吗? Or is this unavoidable? 或者这是不可避免的?

Edit: Here is how I would use it with SignalR: 编辑:以下是我将如何与SignalR一起使用:

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

Your solution will work fine, but you're right that it would block a thread the whole time. 你的解决方案可以正常工作,但你是正确的,它会一直阻塞一个线程。

I think the simplest way to efficiently implement WhenAll() on .Net 4.0 is to use ContinueWhenAll() . 我认为在.Net 4.0上有效实现WhenAll()的最简单方法是使用ContinueWhenAll() It performs an action when all Task s from a collection are finished and returns a Task representing that action. 它在集合中的所有Task完成后执行操作,并返回表示该操作的Task Since we want just that Task , we don't need the action, passing an empty lambda will work: 由于我们只想要那个Task ,我们不需要动作,传递一个空的lambda会起作用:

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

While you're targeting .Net 4.0, if you can use VS2012, then a simpler/better option (IMHO) is to use NuGet to install the async targeting pack and then you can use WhenAll ( TaskEx.WhenAll in that case, since it can't modify the Task that's in the 4.0 framework). 虽然你的目标是.Net 4.0,如果你可以使用VS2012,那么更简单/更好的选择(恕我直言)是使用NuGet来安装异步目标包 ,然后你可以使用WhenAll(在这种情况下是TaskEx.WhenAll ,因为它无法修改4.0框架中的任务。

As a significant added bonus, you can then use async/await in your .Net 4.0 code as well :) 作为一个重要的额外奖励,您可以在.Net 4.0代码中使用async / await :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM