简体   繁体   English

如何取消正在运行的任务?

[英]How to cancel a running task?

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! 当我单击“转义”键Form_KeyDown运行但不取消任务时!

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();
  }
}

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. 通过将取消令牌传递给Task.Factory.StartNew,您不会中止任务。 Let me quote Stephen Toub : 让我引用Stephen ToubStephen Toub

Passing a token into StartNew associates the token with the Task. 将令牌传递给StartNew会将令牌与任务相关联。 This has two primary benefits: 1) If the token has cancellation requested prior to the Task starting to execute, the Task won't execute. 这有两个主要好处:1)如果令牌在任务开始执行之前已请求取消,则该任务将不会执行。 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. 2)如果任务的主体也在监视取消令牌,并抛出包含该令牌的OperationCanceledException(这是ThrowIfCancellationRequested所做的事情),则当任务看到该OCE时,它将检查OCE的令牌是否与Task的令牌匹配。 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). 如果是这样,则该异常被视为对合作取消的确认,并且Task转换为Canceled状态(而不是Faulted状态)。

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();
      }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM