Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are a .NET Task thread's resources returned back to the pool temporarily if the thread is waiting on an async operation to finish?

I have a TPL Task that does two things. First, it calls a web service. Second, it inserts some data into a database. I have up to 20 Tasks started at one time doing this same thing over and over again. All they do all day is call web services and insert data into a database.

I'm fairly new to TPL in .NET. I've done some stuff with background worker processes and async web services.

The web service call and the database insert are both blocking calls within the thread the Task is running in.

I understand that under the covers, when you use Tasks, .NET manages a thread pool for you. Yes?

Would the thread pool have more threads at its disposal if I made the service call and database call with async and await() instead of making them blocking calls?

My theory (and I'm not sure why I think this) is that the thread is busy doing nothing while waiting on the blocking web service and can't return its resources temporarily to the pool. But I wonder if the Tasks were waiting for async calls to finish whether the main Task thread would be able to switch to let other stuff process while waiting.

Is my theory right? Or am I making stuff up?

I'm using c# and .NET 4.0, but I could go to 4.5 if needed.

like image 729
Trevor Avatar asked Aug 15 '14 07:08

Trevor


People also ask

What happens to thread pool after it finishes its task?

Once a thread in the thread pool completes its task, it's returned to a queue of waiting threads. From this moment it can be reused. This reuse enables applications to avoid the cost of creating a new thread for each task.

Is task run async?

NET, Task. Run is used to asynchronously execute CPU-bound code.

How do you wait for ThreadPool to finish?

You can wait for a task to finish in a ThreadPoolExecutor by calling the wait() module function.

Does task result block thread?

Yes Accessing Task. Result is the same as calling Task. Wait(). Accessing the property's get accessor blocks the calling thread until the asynchronous operation is complete; it is equivalent to calling the Wait method.


1 Answers

The answer is yes. Although technically it's not "waiting" for the async operation to complete (otherwise there would be no benefit to async). Under the hood there is a callback delegate that is run when the async operation completes, which is what allows your calling thread to proceed without blocking. It's the async/await magic that turns these 'continuations' into a linear looking piece of code.

Because you are using a threadpool thread, when it hits an await the thread will return to the threadpool. The thing to be careful with here is that the normal behaviour is when the awaited operation completes it will try to get back onto the thread that it was started on (now probably being used by another Task) so you may observe latency problems in getting the results back as threadpool threads are now tied up starting other tasks. Over time the threadpool will try to adjust the number of available threads to meet demand but you might find this doesn't happen quickly enough if you work comes in bursts. The result will be apparently poor performance as you may only have a small number of threads available.

like image 63
Jack Ukleja Avatar answered Sep 19 '22 20:09

Jack Ukleja