This post is based on one of the questions I answered on StackOverflow, in which the questioner wants to cancel the task when it's taking too long to respond, i.e., taking too much time in execution and returning the result. But, when I tried to provide the answer to that question, I found there is no direct way to cancel the task when making the call to Web Service or making the call to Database to get the data via third-party library ( XenAPI in my case) which is hanging up the application and not allowing it to proceed. To understand this, have a look at the below code.
- Var task = Task.Factory.StartNew(()=> CallWebServiceandGetData());
The above line of code is creating the task which is making calls to the webservice to get the data. Now, the developer wants to write a code in such a way that if the task takes more than 10 seconds, it gets canceled. However, in TPL library, there is no way to cancel the task, i.e., there is no direct method or there is no other way to make this task cancel because task.Cancel() or task.Abort() like methods do not exist in TPL. The below post is about how a developer can really abort a task.
Aborting thread vs Cancelling task
What is the difference between aborting thread and cancelling task.
Aborting thread
System.Treading is a library provided for threading prior to TPL library. (Just to note - old System.Threading is still part of .NET framework but TPL provides more control on Task which is wrapper around thread). In this library, to abort thread there is a method called Abort() available. With the help of this method, a developer can ask execution environment (CLR) to abort the thread. Below is an example code for the same.
- Thread newThread = new Thread(() => Console.WriteLine("Test"));
- newThread.Start();
- Thread.Sleep(1000);//sleeping main thread
- newThread.Abort();main thread aborting newly created thread.
Cancelling Task
In the newer library, TPL (System.Threading.Tasks), there is no direct method which cancels or aborts the underlying thread. But there is a way to cancel a task by using CancellationTokenSource class which allows you to pass the CancellationToken as one of the input parameters when you create the task. (more on this is discussed below). Below is the code for cancelling the task.
- var source = new CancellationTokenSource();
- CancellationToken token = source.Token;
- Task.Factory.StartNew(() => {
- for(int i=0;i< 10000;i++)
- {
- Console.WriteLine(i);
- if (token.IsCancellationRequested)
- token.ThrowIfCancellationRequested();
- }
- }, token);
- source.CancelAfter(1000);
So, the above code makes use of CancellationTokenSource and CancellationToken provided by it. In the above code, CancellationTokenSource calls the method CancelAfter which sets taskCancellation flag. This flag is watched inside delegate via IsCancellationRequested property on CancellationToken. And once it sees in the for loop that IsCancellationRequested flag is true, it calls the ThrowIfCancellationRequested() method and cancels the thread.
So, in simple terms, abort thread allows the developer to abort executing thread and CancellationToken in new TPL library does the same thing, which is called cancelation of task. So basically, newer(TPL) and older(Threading) have different way to cancel/abort thread.
But one of the major differences between Abort() thread and Cancel task is that Abort() can leave application in an inconsistent state ( on Abort(), the system immediately aborts the thread, not allowing you to perform any operation to put application in consistent state ), especially when doing file operation or doing create/update operation , so it is better to take care when aborting thread or writing code in such a way that the application remains in consistent state. That is one of the reasons TPL come up with Cancellation mechanism, so those who write the code can watch cancellation flag and if it gets true, then they can write the code to put application in consistence state.
Returning to problem of Cancelling task
By reading the above section of “Cancellation Task”, one can say there is a provision to cancel task which in turn cancels the thread also and puts the system in consistent state, so it’s a better approach. But, if we now go back to the scenario where a task is created to fetch the data from webService or Database which is taking too much long time, the code will be like below with cancellation mechanism.
- var source = new CancellationTokenSource();
- CancellationToken token = source.Token;
- Task.Factory.StartNew(() => {
- try
- {
- //below is third party library(XenAPI) method
- HTTP_actions.put_import(…//parameter of method);
- //instead of this there can be database call to get data
- //which takes too much time
- }
- catch (HTTP.CancelledException exception)
- {
- }
- //execution never comes here till above method get complete
- if (token.IsCancellationRequested)
- token.ThrowIfCancellationRequested();
- }, token);
- source.CancelAfter(1000);

Muhanad AhmadPosted Apr 24, 2019, 11:38 AM
Hello, In your last code, shouldn't you start the "checking task" before the "DoWork()" it seems like the wait will stop the checking task from executing until the wait is done.
Saravanan PonnusamyPosted Jul 4, 2018, 8:54 PM
Im using the same concept to cancel some task in my web application... is there is any way to use response.write or response.redirect method inside the task section instated of Console.writeline???? .. because once the for-loop inside the task finished ..i want show task completed message alert to the user..