I was reading about the Task Parallel Library and the article said:
In the .NET Framework 4, tasks are the preferred API for writing multi-threaded, asynchronous, and parallel code
But it also says they use the ThreadPool behind the scenes. What I'm having difficulty figuring out is if Tasks should only be used when you'd use a ThreadPool (and so "Thread versus Task" would be equivalent to "Thread versus ThreadPool"), or if Microsoft intended for Tasks to be used anywhere multiple threads are required, without the considerations inherent to the "Thread versus ThreadPool" dilemma.
So, should Tasks be used anywhere multiple threads are required?
Thread pools do not make sense when you need thread which perform entirely dissimilar and unrelated actions, which cannot be considered "jobs"; e.g., One thread for GUI event handling, another for backend processing. Thread pools also don't make sense when processing forms a pipeline.
Differences Between Task And ThreadThe Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. The task can return a result.
By default, TPL types like Task and Task<TResult> use thread pool threads to run tasks. You can also use the thread pool by calling ThreadPool.
For example, a desktop application providing functionality like editing, printing, etc. is a multithreaded application. In this application, as printing is a background process, we can perform editing documents and printing documents concurrently by assigning these functions to two different threads.
The design advantage of using tasks is that you hand over the nitty-gritty of threading to the runtime, which presumably could accomplish the threading tasks using a less buggy, more optimal solution. I know certain Task-based paradigms, such as PLINQ, allow you to hint at which strategy the runtime should adopt, so that the question of "to Threadpool or not to Threadpool" could be handled directly.
The switch to this model is analogous to the switch to a Managed GC-ed language versus a language that requires you to clean up your own memory. There will always be arguments in favour of the latter, but Garbage Collection is getting so optimized now that it's practically a non-issue. Ideally, the runtime switching mechanism for Tasks will evolve and get better. So in theory, your application written and compiled for .NET 4 could get faster with better implementations of the runtime, without further recompilation. Also, threading code is notoriously hard to get right, so any mechanism that hides those details is good for the programmer.
Whether those benefits outweigh potential detriments, such as edge cases that the runtime doesn't deal with well, is something that should be considered case-by-case. I would certainly try to not optimize early here, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With