有没有办法取消已取消任务中方法的执行?
Is there a way to cancel execution of method in cancelled task?
我有一个问题,我找不到任何答案。这是我第一个使用线程和任务的项目。当我的任务被取消时,它一直在执行耗时的方法。
现在我不知道如何停止执行方法和任务。
下面是一个运行任务的循环。每个任务都是 运行 一个 ParseHorseData
方法,它还运行其他几种方法。执行它们有时会花费很多时间。
任务取消后,在await Task.WhenAll(tasks);
完成之前,需要很多时间。
所以,如问题中,有没有办法取消执行已取消任务中的方法?
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
传递给它调用的方法,并且:
- 使用
ThrowIfCancellationRequested
定期轮询取消。这种方法更适合 CPU-bound 循环。
- 使用
Register
执行取消操作。这种方法更适合与不基于 CancellationToken
的消除系统连接。
在这种情况下,听起来轮询是合适的。我强烈建议通过 ThrowIfCancellationRequested
而不是 IsCancellationRequested
进行轮询,因为当任务被取消时,它应该在 await
ed 时抛出一个 OperationCanceledException
。这就是调用代码知道它已被取消的方式。
示例:
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;
}
...
}
});
我有一个问题,我找不到任何答案。这是我第一个使用线程和任务的项目。当我的任务被取消时,它一直在执行耗时的方法。
现在我不知道如何停止执行方法和任务。
下面是一个运行任务的循环。每个任务都是 运行 一个 ParseHorseData
方法,它还运行其他几种方法。执行它们有时会花费很多时间。
任务取消后,在await Task.WhenAll(tasks);
完成之前,需要很多时间。
所以,如问题中,有没有办法取消执行已取消任务中的方法?
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
传递给它调用的方法,并且:
- 使用
ThrowIfCancellationRequested
定期轮询取消。这种方法更适合 CPU-bound 循环。 - 使用
Register
执行取消操作。这种方法更适合与不基于CancellationToken
的消除系统连接。
在这种情况下,听起来轮询是合适的。我强烈建议通过 ThrowIfCancellationRequested
而不是 IsCancellationRequested
进行轮询,因为当任务被取消时,它应该在 await
ed 时抛出一个 OperationCanceledException
。这就是调用代码知道它已被取消的方式。
示例:
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;
}
...
}
});