How to cancel a running task?

10,590

You are doing all ok except the fact that you need to stop your code from running inside your method. By passing cancellation token to Task.Factory.StartNew you are not aborting the task. Let me quote Stephen Toub:

Passing a token into StartNew associates the token with the Task. This has two primary benefits: 1) If the token has cancellation requested prior to the Task starting to execute, the Task won't execute. Rather than transitioning to Running, it'll immediately transition to Canceled. This avoids the costs of running the task if it would just be canceled while running anyway. 2) If the body of the task is also monitoring the cancellation token and throws an OperationCanceledException containing that token (which is what ThrowIfCancellationRequested does), then when the task sees that OCE, it checks whether the OCE's token matches the Task's token. If it does, that exception is viewed as an acknowledgement of cooperative cancellation and the Task transitions to the Canceled state (rather than the Faulted state).

You need to manually check if your token was cancelled and throw operation canceled exception, something along these lines:

 private async void Search_Button_ClickAsync(object sender, EventArgs e)
    {
      cToken = cTokenSource.Token;
      await (Task.Factory.StartNew(() =>
               {

               for(int i=0;i<yourtaskcount;i++)
               { 
                 cToken.ThrowIfCancellationRequested();

                  //long work
               cToken));
    }
    private void Form_KeyDown(object sender, KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Escape)
      {
        tokenSource.Cancel();
      }
    }
Share:
10,590

Related videos on Youtube

PEYMAN
Author by

PEYMAN

Updated on June 04, 2022

Comments

  • PEYMAN
    PEYMAN almost 2 years

    I want to cancel a running task (when the users presses the escape key). when i click on "escape" key Form_KeyDown run but doesn't cancel task!

    CancellationTokenSource tokenSource = new CancellationTokenSource();
    CancellationToken token=new CancellationToken();
    
    private async void Search_Button_ClickAsync(object sender, EventArgs e)
    {
      token = tokenSource.Token;
      await (Task.Factory.StartNew(() =>
               {
                 //...my program
               },
               token));
    
    private void Form_KeyDown(object sender, KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Escape)
      {
        tokenSource.Cancel();
      }
    }
    
    • SᴇM
      SᴇM about 6 years
      Possible duplicate of How do I abort/cancel TPL Tasks?
    • mjwills
      mjwills about 6 years
      please help me this code is not working! What do you mean by 'not working'?
  • PEYMAN
    PEYMAN about 6 years
    thanks dear friend but i need to cancel immediately after click "escape"
  • MistyK
    MistyK about 6 years
    @PEYMAN It depends how your business logic look like and how often you can check for cancellation. You can also abort the task but it's not recommended. Check here: stackoverflow.com/questions/4359910/… You can also cancel the task, and let it be cancelled after some time in the background. Your UI can pretend that it's already cancelled enable buttons/allow next run to be started. You need to be careful about thread safety though.
  • PEYMAN
    PEYMAN about 6 years
    @Default if i use ThrowIfCancellationRequested then task cancel immediately?
  • MistyK
    MistyK about 6 years
    @PEYMAN yes it does but it's equivalent to the previous solution but shorter
  • PEYMAN
    PEYMAN about 6 years
    @Default can you give me code of my example program with your solution?