如何并行化ASP.NET

时间:2016-06-29 14:15:38

标签: c# asp.net multithreading parallel-processing async-await

在Asp.NET MVC应用程序中,我有一个项目,其中包含要跟踪的活动图。

项目没有单个根但有多个根。 每棵树都可能是复杂而深刻的,每个节点都依赖于日期和细粒度用户权限等其他节点。

每次在节点上进行操作时,我都需要处理所有项目图 因为即使不同的分支也相互依赖。

结构平面存储在SqlServer DB中。

为了创建树,我有一个递归函数,可以为每个节点创建一些数据(在当前用户的上下文中)。

例如,我有一个包含3000个节点的项目,只需一次调用即可创建整个图形,处理时间超过2秒。

public static List<Nodes> GetProject(...) {
  var list = new List<Nodes>;
  CreateTreeRecursive(...);
  return list;
}

请记住,我有多个根。这让我可以独立地并行化每个分支的工作和处理。

如果我使用Task.Run或Parallel.ForEach并行执行,则创建整个图形的时间在15到50毫秒之间,快50倍。

public static List<Nodes> GetProject2(...) {

  var list = new List<Nodes>;

  Parallel.ForEach(...,
    (root) => {
      ...
    });

  return list;
}

坏消息是你不应该在ASP.NET中创建线程。

在特定情况下,我没有多个并发用户,但拥有约200名用户 你无法确切地知道。

另一件事是项目的根源可能很多,最多100个,所以很多线程会 被创造。

这个解决方案很简单但不适用。

有没有办法以简单的方式做到这一点,或者我唯一的选择是将工作卸载给某些人 可以跨越多个线程并等待异步的外部服务?

如果是这种情况,我会很感激一些建议吗?

要清楚这是为项目上的任何用户交互而进行的操作。 我不能缓存结果,太不稳定了。我不能在某个地方入队,最终得到结果。

由于

1 个答案:

答案 0 :(得分:1)

  

坏消息是你不应该在ASP.NET中创建线程。

事实并非如此,这种错误的假设阻碍了正确的解决方案。

您可以创建线程。您可能想到的风险是您可能耗尽线程池的容量。这一般不容易做到。

您的线程受CPU限制。这意味着您的服务器在池耗尽之前很久就会过载。池容量不是您的限制因素。

通过一些假设我们可以构成一个具体的场景:一个8核心服务器在8个线程(这里可以像这样运行)饱和。但是,如果少于100个线程,则不会将线程池视为重载。 (实际数量各不相同.100在各种情况下应该是安全的。)

此外,Parallel.ForEach使用池线程。它不会创建有意义的线程数量。它也不会占用每个输入项的一个线程。

我在这里看不到任何担心。