Task.Run vs ThreadPool.QueueUserWorkItem
Solution 1
ThreadPool.QueueUserWorkItem
is just the older implementation (introduced in .NET 1.1) of doing the same job as Task.Run
(introduced in .NET 4.5).
Microsoft tries to avoid breaking backwards compatibility in .NET.
Something written for .NET 1.1 can be compiled and ran in .NET 4.5 with (usually) no changes.
Breaking changes are usually from compiler changes, not framework changes, like the variable declared in a foreach
used inside a lambada behaving differently in C# 5 and newer.
There is no real reason to use ThreadPool.QueueUserWorkItem
when you have Task.Run
.
One ending point: ironically, things have actually come full circle with HostingEnvironment.QueueBackgroundWorkItem(...)
.
It lets you run something on a background thread in a ASP.NET environment and let the background work be notified of AppDomain
shutdowns by the web server (which can frequently happen during long periods of inactivity).
Solution 2
One difference between ThreadPool.QueueUserWorkItem
and Task.Run
I recently realized is the way they handle exceptions.
If an unhanded exception occurs inside ThreadPool.QueueUserWorkItem
and not handled by global exception handler, it will crash parent thread. On the other hand, unhanded exceptions from Task.Run
thread will not get propagated until you await
or Task.Wait
.
Stefano
Updated on August 15, 2022Comments
-
Stefano over 1 year
Not a subject expert I'm trying to understand more of the async world available in .NET. Task.Run and ThreadPool.QueueUserWorkItem both allow dispatching work on a pool thread but what are the differences or, if you prefer, pros and cons of the two? Following is my list of pros. Not sure if it is complete or even correct.
ThreadPool.QueueUserWorkItem pros:
- Possibility of passing an argument
Task.Run pros:
- Possibility of providing a CancellationToken
- Possibility of waiting Task completion
- Possibility of returning a value to calling code