【问题标题】:Is this a correct .NET 4 implementation for .NET 4.5's WhenAll?这是 .NET 4.5 的 WhenAll 的正确 .NET 4 实现吗?
【发布时间】:2012-09-12 23:17:26
【问题描述】:

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

我为此找到了一个完美的函数:Task.WhenAll。然而,这是 .NET 4.5 中的一个新功能,我仍然停留在 .NET 4 上。

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

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

我认为它在功能上可以工作,但我不会为新任务获得额外的阻塞线程吗?还是这是不可避免的?

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

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

【问题讨论】:

  • 出于好奇,您是否尝试过反编译或查看 .NET 4.5 版本的源代码以了解您的接近程度? (referencesource.microsoft.com/netframework.aspx)
  • 不,我没有这样做。实际上我从来没有这样做过。立即下载 JustDecompile。
  • 我正在下载源代码,希望已经为您解答,但是下载需要一点时间...
  • 哇,看来我还差得很远:P。在我看来,这个实现类似于 svick 在 ContinueWhenAll 的实现中看到的。 IE。为每个任务安排继续。然而,这是一个相当复杂的功能,我没有得到所有正在发生的事情。

标签: c# multithreading task-parallel-library


【解决方案1】:

虽然您的目标是 .Net 4.0,但如果您可以使用 VS2012,那么更简单/更好的选择 (恕我直言) 是使用 NuGet 安装 async targeting pack,然后您可以使用 WhenAll (TaskEx.WhenAll 在这种情况下, 因为它不能修改 4.0 框架中的 Task)。

作为一项重要的额外奖励,您还可以使用async/await in your .Net 4.0 code :)

【讨论】:

  • 可惜我们还在 VS2010。不过我会记住的。最后的话可能会有用。
【解决方案2】:

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

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

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

【讨论】:

  • 我想知道它是如何在水下工作的。 IE。它可以在不创建额外线程的情况下完成这项工作吗?
  • 我还没有看源码,但是我很确定它不会因为阻塞而浪费一个线程。
  • 我现在查了一下,它确实没有阻塞线程,它为集合中的每个任务安排了一个延续,当全部执行时,动作执行。
  • @svick,就返回的任务状态而言,我认为这不等于.WhenAll。对于WhenAll,如果任何返回的Task出现故障,则返回的任务出现故障,如果任何返回的Task被取消,则返回的任务被取消。在此版本中,返回的 Task 将处于 RanToCompletion 状态,而不管其前项的完成状态如何。为了使其等效,该操作需要不平凡并处理此逻辑。
猜你喜欢
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 2019-09-01
  • 2012-08-25
相关资源
最近更新 更多