Tuesday, 25 February 2014

Continue with this task when you finish the other task in C#.

So what is it about ContinueWith that had made writing asynchronous programming suddenly easy and beautiful. You see a long long time ago before the advent of tasks in the .net framework 4, those of you who were born at that time in the era of .net framework 3.5 will agree with me that writing asynchronous code was very difficult, reading one was even more difficult and if I remember properly my head used to throw endless exceptions at each line I came across.

Why am I this happy you may ask? You see then when one writes multi-threaded application, one has many demons to fight. If you are not fighting with shared state management, you will be fighting deadlocks or one of my favourite race condition. But now are there no more of those fights? Well almost. In this post I will look into what makes tasks awesome.

Enter ContinueWith 

ContinueWith is the icing on the cake of Task, the secret recipe that has being added to the TPL which have made every dot net programmer's life easier. Before, parallel programming used to be the exclusive domain of the big boys. But now, anyone can just write an asynchronous program, by just throwing in a couple of Task.Run() or Task.Factory.StartNew() with a garnishing of async/await.

So how does it work under the hood

ContiuneWith is implemented with a task object which executes asynchronously after the main (antecedent) task has been executed.  This task executes immediately if the main task has finished executing or it waits until the main tasks' execution. ContinueWith can be chained and its execution can be controlled depending on the main tasks' result.It has many overloads and accepts other parameters like TaskContinuationOptions, CancellationToken and TaskScheduler.

TaskContinuationOptions is used to control how the continuation task behaves and when it is scheduled depending on the result of the main task action.

CancellationToken is passed to the ContinueWith task action so as to notify the it to end immediately whenever the Cancel() method is called . When this method is called, it sets the IsCancelRequested property of the token source to true. The ContinueWith can listen to this property so as to know when the Cancel is called.

TaskScheduler is a low level object that is used in queuing and executing tasks in the ThreadPool. You can pass a custom TaskScheduler when you want to control how the task is queued and executed.

            var cancellationToken = new CancellationToken();
            Task.Run<int>(() =>
            {
               //Long running operations
            }, cancellationToken)
                .ContinueWith(
                    (result=>
                    {
                        //Operation that you want to execute if the task was
                        cancelled
                    },
                    TaskContinuationOptions.OnlyOnCanceled)
                .ContinueWith((response=>
                {
                    //Operation that you want to execute if the task completed.
                }, TaskContinuationOptions.OnlyOnRanToCompletion);


The beauty of the ContinueWith() method is that it enables one to write asynchronous code synchronously. Also it enables one to individually respond to the different states in which a task can terminate in (Faulty state, Cancelled state and Completed state) thereby simplifying the code paths and making the code easier to read and understand.

Conclusion

One reason why I find the ContinueWith() method of the Task class so awe inspiring is that I no longer have to wait if I don't want to, I no longer have to do an endless checking of the state of my background task like in other asynchronous patterns and in threads if I don't want to. With ContinueWith I can just chain the paths that I want the execution of my code to take depending on the result of the main task and then continue on my merry way without giving myself a migraine headache. And by throwing into the mix a few async/await, I can just propagate the async nature of the code through the call chain so that callers will be aware and take appropriate actions.  Happy coding....

No comments:

Post a Comment