Reputation: 217
I understand that when using async and await on a method called on the UI thread that the UI thread can be freed to do other work while awaiting some IO to complete. If I use the async await on a method called by a threadpool thread what happens to the that threadpool thread while the IO completes? Is it returned to the pool? When the IO is completed what thread completes the method in this latter case?
Upvotes: 6
Views: 1786
Reputation: 457187
If I use the async await on a method called by a threadpool thread what happens to the that threadpool thread while the IO completes? Is it returned to the pool?
Yes, the thread pool thread is returned to the thread pool.
When the IO is completed what thread completes the method in this latter case?
By default, await
will capture a current "context", and use that to resume the async
method when the await
completes. This "context" is SynchronizationContext.Current
unless it is null
, in which case the "context" is TaskScheduler.Current
.
In the UI case, there's a UI SynchronizationContext
that causes the async
method to resume executing on the UI thread. In the thread pool case, SynchronizationContext.Current
is null
, and TaskScheduler.Current
is the thread pool task scheduler. So, the async
method is resumed on a thread pool thread (any arbitrary thread, not necessarily the same thread).
If you want more information on this behavior, I have an async
intro that you may find helpful.
Upvotes: 4
Reputation: 1503250
In that case, the continuation executes on any available thread-pool thread.
In theory it's up to the awaitable to schedule the continuation appropriately, but generally an awaitable captures the current SynchronizationContext
when the async method passes in the continuation, and uses that synchronization context to schedule the continuation when the awaitable has completed. (Module ConfigureAwait
calls etc.)
In the case of the thread pool, there is no synchronization context, so the continuation is just scheduled on any thread pool thread. (The same is true on a console app's main thread - or basically any thread where a synchronization context hasn't been set.)
Upvotes: 4