如何取消正在运行的任务? [英] How to cancel a running task?

查看:168
本文介绍了如何取消正在运行的任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想取消正在运行的任务(当用户按下转义键时)。
,当我单击转义键Form_KeyDown运行但不取消任务时!

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


推荐答案

您一切正常,除了您需要停止代码在您的方法中运行之外。通过将取消令牌传递给Task.Factory.StartNew,您不会中止任务。
让我引用 Stephen Toub

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:


将令牌传递给StartNew将令牌与任务相关联。
这有两个主要好处:1)如果令牌已在任务开始执行之前请求取消
,则该任务将不会执行
。它会立即将
转换为已取消,而不是转换为正在运行。如果
无论如何在运行时都会被取消,这避免了运行任务的成本。 2)如果
任务的主体也在监视取消令牌,并引发包含该令牌的
OperationCanceledException(这就是
ThrowIfCancellationRequested所做的事情),那么当任务看到OCE时,
它检查OCE的令牌是否与任务的令牌匹配。如果
确实如此,则该异常被视为对合作性
取消的确认,并且Task转换为Canceled状态(而不是
而不是Faulted状态)。

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

这篇关于如何取消正在运行的任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆