【发布时间】:2016-06-29 14:15:37
【问题描述】:
在一个 Asp.NET MVC 应用程序中,我有一个带有要跟踪的活动图的项目。
一个项目没有一个根,而是多个根。 每棵树都可能很复杂且很深,每个节点都依赖于其他节点,例如日期和细粒度的用户权限。
每次对节点进行操作时,我都需要处理所有项目图 因为即使是不同的分支也相互依赖。
该结构以平面形式存储在 SqlServer 数据库中。
为了创建树,我有一个递归函数,它做了很多事情来为每个节点(在当前用户的上下文中)创建一些数据。
例如,我有一个包含 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 个,所以很多线程会 被创建。
这个解决方案很简单,但不适用。
有没有办法以简单的方式做到这一点,或者我唯一的选择是将工作分担给一些人 可以跨多个线程并异步等待的外部服务?
如果是这种情况,我会很感激一些建议?
需要明确的是,这是针对项目上的任何用户交互进行的操作。 我无法缓存结果,太不稳定了。我无法在某处排队并最终得到结果。
谢谢
【问题讨论】:
-
此类问题通常由缓存处理,您的数据源是否可行?您可能无法缓存整棵树,但树的子集可能是可缓存的,无需重新计算。
-
用户真的需要知道3000个节点的状态吗?如果它们是不同的分支并且它们相互依赖,那么对我来说,它们并不会真的觉得它们是不同的分支。根据您的说法,我们不可能解决您的问题,而且我们最多可以提供广泛的一般性建议,这对于解决问题并没有真正有用,因为我们不知道您知道什么。
-
@ScottChamberlain 是的,我可以缓存分支,但如果编辑频繁,我可能会有非常短暂的缓存条目。每改变一个最小的数据片段就意味着分支的失效。
-
@GeorgeStocker 一个分支只能在开始日期依赖另一个分支。大多数时候用户不需要整张图片,但有时是必要的。
-
我开始承认(我已经考虑过)我需要缓存一些东西,但我对 ASP:NET 中的并行化问题非常感兴趣,这将是最简单的解决方案。
标签: c# asp.net multithreading parallel-processing async-await