In an Asp.NET MVC application I have a project with a graph of activities to track.
A project doesn't have a single root but multiple ones. Every tree could be complex and deep and every node depends on the others on things like dates and fine grained user permissions.
I need to process all the project graph every time I do an operation on a node because even different branches depends on each other.
The structure is stored flat in a SqlServer DB.
To create the tree I have a recursive function that do a lot of things to create some data for every node (in the context of the current user).
For example I have a project with 3000 nodes that takes more than 2 seconds to process with a single call that create the entire graph.
public static List<Nodes> GetProject(...) {
var list = new List<Nodes>;
CreateTreeRecursive(...);
return list;
}
Remember that I have multiple roots. This let me to parallelize the work and process every branch indipendently.
If I parallelize the execution with Task.Run or Parallel.ForEach the time to create the entire graph is in the range between 15 and 50 ms, 50 times faster.
public static List<Nodes> GetProject2(...) {
var list = new List<Nodes>;
Parallel.ForEach(...,
(root) => {
...
});
return list;
}
The bad news is that you shouldn't create threads in ASP.NET.
In the specific case I don't have many concurrent users, but with an audience of ~200 users you can't really know for sure.
The other thing is that the roots in a project could be many, up to 100, so many threads would be created.
This solution would be so simple but is inapplicable.
Is there some way to do this in a simple manner or my only option is to offload the work to some external service that can span multiple threads and waiting asyncronously?
If this is the case I would appreciate some suggestions?
To be clear this is an operation that is made for any user interaction on the project. I can't cache the result, is too volatile. I can't enqueue somewhere and eventually get the result.
Thanks