Basics of Task Parallel Programming in .
NET ????Abid ZaidiBlockedUnblockFollowFollowingJun 4Multithreaded vs Single-threaded programsTask Parallel Library?!To take advantage of multicore systems programmers write parallel programs.
These programs will solve problems by breaking them into small pieces and executing them in parallel or concurrently on multiple cores or processors.
The legacy way of writing multithreaded programs in .
NET is worker-oriented in which your program should be responsible for scheduling and management of threads.
But with Task Parallel Library(TPL) things have been easier, its focus is task-oriented where focus is on what to do rather than how to do.
TPL schedules threads on the thread pool and allows more functionality over the legacy threading techniques.
In this article, I will be going through the TPL in different yet basic aspects.
I’ve created code gists on GitHub and linked them over here, I’m not going to write a very long explanation on what’s happening with the code but an overview would be sufficient.
So lets kickstart with the basics!Different ways to create TasksThere are multiple ways to create a task, you may choose which suits you best.
The simplest one is using the Factory’s static method.
The rest of them create an instance of the Task class and call the Start method which is then passed to the task scheduler.
(Few of the tasks call the printMessage Method which only consoles a message without returning anything)Setting Task StatesWhen there are many tasks and you need to give each task a separate identification, set the state by passing a costructor argument.
You may also pass a variable of your choice and do computations with it.
Capitalizing on the previous example following are a number of ways to set states while creating task instances.
Returning Result from a TaskTasks can return results in an asynchronous fashion.
When Result property of Task is called it waits until the task is finished.
In the following example, there are two tasks one is created using the task factory.
The other task is an example using the anonymous method.
Anonymous methods are the most common technique while calling task constructors.
Canceling TasksTo cancel a task we need a CancellationToken which resides within a property of CancellationTokenSource, this token is then used as a constructor argument while creating Task instance.
To Cancel a task simply call the Cancel() method on cancellation token source.
The gist below shows how to cancel a task along with 3 different ways to go about monitoring your task after cancellation.
In the first example Task is monitored by polling whether it has been cancelled or not.
If it has we throw an exception which is addressed later on, in this article.
The second example registers a delegate to monitor when the tasks get cancelled.
In the third example WaitHandle.
WaitOne() method is used which waits until the task has been cancelled.
Go through the code below, it might take a while to sink in …Composite Cancellation of Multiple TasksDependent tasks need to be cancelled together?.quite easy to solve this when all tasks point to one cancellation source but when there are multiple cancellation sources you could simply link all the Cancellation Token sources to one composite source using the CreateLinkedTokenSource method which takes all sources as parameters.
Whenever one of the sources are cancelled all tasks are cancelled together.
Refer to the code which is a simplified version where i haven’t shown different task instances but i have shown how to link multiple token sources and monitoring the cancellation activity using waithandle’s WaitOne() method.
Waiting for TasksAfter the task is invoked there are few options on how to wait for them to complete.
Individually you could call the Wait() method over a task instance which has a few overloads discussed in the gist below.
Task class provides static methods that can wait on one or many tasks with WaitAny and WaitAll methods respectively.
Handling Exceptions in TaskOn cancelling tasks we saw that an operation cancelled exception is thrown whenever the token source is cancelled.
While calling Wait on all the task in a try catch block will catch all exceptions in Aggregate type.
First example shows iterating through InnerExceptions property and accessing the details of each exception.
Second example uses an iterative handler which can also be used to handle custom exceptions.
A third alternate is to access Task properties mentioned in the end.
Another way to handle an exception is using a custom escalation policy which can be done by adding an event handler on TaskScheduler.
UnobservedTaskExceptionLazy TaskLazy task is when you want to execute tasks in parallel only when the result is required.
The lazy variable is not initialized until it is read, avoiding potentially expensive computing until they are needed or in some cases, avoiding work for variables that won’t be needed at all.
Thanks for reading ????.. More details