1
votes

I am looking for a way to cancel a task that was already started and then restart the same task with new input data.

Below is the sample code which I have written but it is not working.

private CancellationTokenSource _cancellationTokenSource;
public public async Task DoSomething(string input)
{
    _cancellationTokenSource.Cancel(true);
    _cancellationTokenSource = new CancellationTokenSource();
    try
    {

        Task.Run(async () =>
        {
            //Asynchronous method code here which uses input like database operations.
            await doSomeDataBaseOperationAsync(input);
        }, _cancellationTokenSource.Token);
    }
    catch { }
}

Can someone help me with it?

1
Cancellation is hand made; you have to check you token state to see if a cancellation has been requested, and do whatever you have to to actually cancel. - Kilazur
What is not working? The place from where you are calling DoSomething you can simply call _cancellationTokenSource.Cancel(true); which will cancel the task and then call the method again. Is it not working? - RBT
cancellationTokenSource.Cancel(true); this code before initialization, does it work ? - Mrinal Kamboj
Also what is that cancellationTokenSource variable inside DoSomething method? It doesn't seem to be defined anywhere in your code block. - RBT
Basically my doSomeDataBaseOperationAsync(input) is still getting executed with old input and then starts with new input. - Suraj Mittal

1 Answers

0
votes

You need to make a manual check in your method doSomeDataBaseOperationAsync which is getting executed asynchronously as shown in the code snippet below. The way I usually do is check the state of the cancellation token source once at the starting of the method itself. If cancellation is not requested till that time then just go ahead and execute the entire function body.

But nobody can stop you from making that check at more critical junctures or milestones inside your method e.g. you might want to recheck the cancellation token state once before firing the DB call as well.

Word of Caution: You just need to make sure that whenever you make such a check several time during the execution of the method and returning mid way then you aren't leaving the state of your object in an inconsistent state. If you don't alter any member variables of your class in such a method then you should be good.

private void doSomeDataBaseOperationAsync(input)
{
   if (_cancellationTokenSource.IsCancellationRequested)
     return; //stop any further processing.
   //do some processing and calculations on the client side
   //.....
   //.....
   //.....
   //make a check again before firing DB request
   if (_cancellationTokenSource.IsCancellationRequested)
     return; //stop any further processing.
   //Do database stuff. cancellation has not been requested. Process the DB request.
}