有没有办法取消取消任务中方法的执行? [英] Is there a way to cancel execution of method in cancelled task?

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

问题描述

我有一个问题,我还没有找到任何 answear.这是我使用线程和任务的第一个项目.当我的任务被取消时,它一直在执行耗时的方法.

I have a problem, that I could not find any answear yet. And this is my first project with use of threading and Tasks. When my task is cancelled, it keeps executing time consuming method.

现在我不知道如何与任务一起停止方法的执行.

Right now I have not idea how to stop execution of the method together with the task.

下面是一个循环,它运行任务.每个任务都运行一个 ParseHorseData 方法,该方法还运行其他几个方法.执行它们有时需要很多时间.

Below is a loop, that runs tasks. Every single task is running a ParseHorseData method, that runs also several other methods. Execution of them takes sometimes a lot of time.

任务取消后,在await Task.WhenAll(tasks);之前,需要很多时间.

After the task is cancelled, before await Task.WhenAll(tasks); is completed, it takes a lot of time.

那么,正如问题中所说,有没有办法取消已取消任务中方法的执行?

So, as in the question, is there a way to cancel execution of method in cancelled task?

List<Task> tasks = new List<Task>();
int loopCounter = 0;
int taskCounter = 0;

//for all races in the file
for (int i = 0; i < _allRaces.Count; i ++)
{
    int j = i;

    if (TaskCancellation == true)
    {
        break;
    }

    Task task = Task.Run(async () =>
    {
        while (!_cancellationToken.IsCancellationRequested)
        {
            loopCounter++;

            ProgressBarTick("Requesting historic data", loopCounter, _allRaces.Count, 0);

            //if the race is from 2018
            if (_allRaces[j].RaceDate.Year == 2018)
            {
                Category = _allRaces[j].RaceCategory;
                Distance = _allRaces[j].RaceDistance.ToString();

                //for all horses in the race
                for (int h = 0; h < _allRaces[j].HorseList.Count; h++)
                {
                    HorseDataWrapper horse = new HorseDataWrapper();


                    //TIME CONSUMING
                    horse = ParseHorseData(_allRaces[j].HorseList[h], _allRaces[j].RaceDate);
                    _allRaces[j].HorseList[h] = horse;
                }
            }

            taskCounter++;

            if (loopCounter >= _allRaces.Count)
            {
                ProgressBarTick("Testing on historic data", taskCounter, _allRaces.Count, 0);
            }
        }
    }, _tokenSource.Token);

    tasks.Add(task);
}

try
{
    await Task.WhenAll(tasks);
}
catch (TaskCanceledException)
{
    //
}
finally
{
    _tokenSource.Dispose();
}

推荐答案

有没有办法取消已取消任务中方法的执行?

is there a way to cancel execution of method in cancelled task?

所有取消都是合作的.正在执行的方法必须将 CancellationToken 传递给它调用的方法,并且:

All cancellation is cooperative. The method being executed must pass the CancellationToken into the methods that it calls, and either:

  1. 使用 ThrowIfCancellationRequested 定期轮询取消.这种方法更适合 CPU 密集型循环.
  2. 使用Register 取消操作.这种方法更适合与非基于CancellationToken 的取消系统交互.
  1. Periodically poll for cancellation using ThrowIfCancellationRequested. This approach is more appropriate for CPU-bound loops.
  2. Take an action on cancellation using Register. This approach is more appropriate for interfacing with non-CancellationToken-based cancellation systems.

在这种情况下,听起来轮询是合适的.我强烈建议通过 ThrowIfCancellationRequested 而不是 IsCancellationRequested 进行轮询,因为当一个任务被取消时,它应该在 awaitOperationCanceledException代码>编辑.这就是调用代码知道它已被取消的方式.

In this case, it sounds like polling is appropriate. I strongly recommend polling via ThrowIfCancellationRequested and not IsCancellationRequested, because when a task is canceled, it should throw an OperationCanceledException when awaited. This is how the calling code knows it has been canceled.

示例:

Task task = Task.Run(async () =>
{
  while (true)
  {
    _cancellationToken.ThrowIfCancellationRequested();
    ...
       //for all horses in the race
       for (int h = 0; h < _allRaces[j].HorseList.Count; h++)
       {
          _cancellationToken.ThrowIfCancellationRequested();
          HorseDataWrapper horse = new HorseDataWrapper();
          horse = ParseHorseData(_allRaces[j].HorseList[h], _allRaces[j].RaceDate);
          _allRaces[j].HorseList[h] = horse;
       }
    ...
  }
});

这篇关于有没有办法取消取消任务中方法的执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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