Reputation: 477
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
Upvotes: 2
Views: 695
Reputation: 171178
The bad news is that you shouldn't create threads in ASP.NET.
This is not true and this wrong assumption is blocking the right solution.
You can create threads. The risk that you probably have in mind is that you might exhaust the capacity of the thread pool. This is not easy to do in general.
Your threads are CPU bound. This means that your server is totally overloaded long before the pool is exhausted. Pool capacity is not your limiting factor.
With some assumptions we can make up a concrete scenario: An 8 core server is saturated at 8 threads (that are runnable like here). But the thread pool would not be considered overloaded if there are less than 100 threads. (The actual number varies. 100 should be safe in a wide range of cases.)
Further, Parallel.ForEach
uses pool threads. It does not create a meaningful amount of threads. It also does not occupy one thread per input item.
I don't see anything here to worry about.
Upvotes: 1