Question

My question might sound a bit naive but I'm pretty new with multi-threaded programming.

I'm writing an application which processes incoming external data. For each data that arrives a new task is created in the following way:

System.Threading.Tasks.Task.Factory.StartNew(() => methodToActivate(data));

The items of data arrive very fast (each second, half second, etc...), so many tasks are created. Handling each task might take around a minute. When testing it I saw that the number of threads is increasing all the time. How can I limit the number of tasks created, so the number of actual working threads is stable and efficient. My computer is only dual core.

Thanks!

Was it helpful?

Solution

One of your issues is that the default scheduler sees tasks that last for a minute and makes the assumption that they are blocked on another tasks that have yet to be executed. To try and unblock things it schedules more pending tasks, hence the thread growth. There are a couple of things you can do here:

  • Make your tasks shorter (probably not an option).

  • Write a scheduler that deals with this scenario and doesn't add more threads.

  • Use SetMaxThreads to prevent unbounded thread pool growth.

See the section on Thread Injection here:

http://msdn.microsoft.com/en-us/library/ff963549.aspx

OTHER TIPS

You should look into using the producer/consumer pattern with a BlockingCollection<T> around a ConcurrentQueue<T> where you set the BoundedCapacity to something that makes sense given the characteristics of your workload. You can make your BoundedCapacity configurable and then tweak as you run through some profiling sessions to find the sweet spot.

While it's true that the TPL will take care of queueing up the tasks you create, creating too many tasks does not come without penalties. Also, what's the point in producing more work than you can consume? You want to produce enough work that the consumers will never be starved, but you don't want to get to far ahead of yourself because that's just wasting resources and potentially stealing those very same resources from your consumers.

You can create a custom TaskScheduler for the Task Parallel library and then schedule tasks on that by passing an instance of it to the TaskFactory constructor.

Here's one example of how to do that: Task Scheduler with a maximum degree of parallelism.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top