I have used most of the Threading library extensively. I am fairly familiar with creating new Threads, creating BackgroundWorkers and using the built-in .NET ThreadPool (which are all very cool).
However, I have never found a reason to use the Task class. I have seen maybe one or two examples of people using them, but the examples weren't very clear and they didn't give a high-level overview of why one should use a task instead of a new thread.
Question 1: From a high-level, when is using a task useful versus one of the other methods for parallelism in .NET?
Question 2: Does anyone have a simple and/or medium difficulty example demonstrating how to use tasks?
Tasks Namespace. Provides types that simplify the work of writing concurrent and asynchronous code. The main types are Task which represents an asynchronous operation that can be waited on and cancelled, and Task<TResult>, which is a task that can return a value.
Causes the operating system to change the state of the current instance to Running. Causes the operating system to change the state of the current instance to Running, and optionally supplies an object containing data to be used by the method the thread executes.
Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The following example calls the parameterless Wait() method to wait unconditionally until a task completes. The task simulates work by calling the Thread.
It is always advised to use tasks instead of thread as it is created on the thread pool which has already system created threads to improve the performance. The task can return a result. There is no direct mechanism to return the result from a thread.
There are two main advantages in using Task
s:
Task
can represent any result that will be available in the future (the general concept is not specific to .Net and it's called future), not just a computation. This is especially important with async
-await
, which uses Task
s for asynchronous operations. Since the operation that gets the result might fail, Task
s can also represent failures.Task
has lots of methods to operate on them. You can synchronously wait until it finishes (Wait()
), wait for its result (Result
), set up some operation when the Task
finishes (ContinueWith()
) and also some methods that work on several Task
s (WaitAll()
, WaitAny()
, ContinueWhenAll()
). All of this is possible using other parallel processing methods, but you would have to do it manually.And there are also some smaller advantages to using Task
:
TaskScheduler
to decide when and where will the Task
run. This can be useful for example if you want to run a Task
on the UI thread, limit the degree of parallelism or have a Task
-level readers–writer lock.Task
s support cooperative cancellation through CancellationToken
.Task
s that represent computations have some performance improvements. For example, they use work-stealing queue for more efficient processing and they also support inlining (executing Task
that hasn't started yet on a thread that synchronously waits for it).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