How are multiple requests to Task.Run handled from a resource management standpoint?

103 views Asked by At

I have some code that I need to "fire and forget," in the sense that the calling code doesn't need to wait around for a response.

If I were to iterate a loop and call this 10,000 times in the span of a second, would I have 10,000 threads floating around, fighting for resources? I have a nightmare of my machine instantly slowing to a crawl.

Alternately, does the thread pool manage these requests, and queue them for resolution?

Put another way, how easy is it to do something stupid with Task.Run().

2

There are 2 answers

2
dmarlow On

When you call Task.Run, you are queueing work to run in the thread pool. If you start a bunch of work, it can take a while to finish as you have limited computing resources. It's easy to bite yourself when running background tasks using Task.Run. It's best to understand the scenario and use the right tools for the job. If you're looking to process lots of background work, take a look at things like TPL, BlockingCollection and Concurrent Collections. Things like Producer/Consumer flows are the right direction, but all depends on what problem you're trying to solve.

2
i3arnon On

So, when you invoke Task.Run it creates a new Task and schedules it on TaskScheduler.Default. That happens to be ThreadPoolTaskScheduler which then queues that task to the ThreadPool. The ThreadPool uses a pool of threads (surprisingly) to slowly go through the work items. The ThreadPool manages its own threads internally and may create more of these when needed.

To your question:

would I have 10,000 threads floating around, fighting for resources?

No, the ThreadPool usually knows how to manage its threads effectively and grows very slowly.

However, you would be allocating a lot of tasks that would wait there taking up space until completed. They may also hold on to other references (usually because of capturing) that take up resources as well.


By the way, if instead of the safer Task.Run you would use Task.Factory.StartNew and pass TaskCreationOptions.LongRunning you would be creating 10,000 background threads.