使用CancellationToken取消特定任务

编程入门 行业动态 更新时间:2024-10-27 02:17:25
本文介绍了使用CancellationToken取消特定任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有以下循环,可能会或可能不会动态创建一系列任务:

I have the following Loop which may or may not create a series of tasks dynamically:

While(CreateNewTask == true) { if(isWorkerFree() && isValidJob() && isExecutable()) { CancellationTokenSource cs = new CancellationTokenSource(); var myTask = Task.Run(() => Execute(cs.token); } }

现在,由于这些任务是动态创建的,我如何跟踪它们并取消特定任务或向特定任务发送取消令牌?随时可能有6-7个任务在运行,我需要该功能才能知道正在运行的任务并取消特定任务.

Now since these tasks are created dynamically, how can I track them and cancel a specific task or send a cancellation token to a specific task? There may be 6-7 tasks running at any time, I need the functionality to know which ones are running and cancel a specific one.

推荐答案

TL; DR; 我认为TPL数据流( msdn.microsoft/en-us/library/hh228603(v=vs.110).aspx )是一个更好的选择,但我会使用TPL回答

TL;DR; I think that the TPL Dataflow (msdn.microsoft/en-us/library/hh228603(v=vs.110).aspx) is a better choice here but I will answer using the TPL

答案 要限制并发性,您需要的是一个限制并发性的调度程序.我建议您查看 msdn.microsoft/library/system.threading.tasks.taskscheduler.aspx 并搜索LimitedConcurrencyLevelTask​​Scheduler.

Answer To limit the concurrency, what you need is a scheduler that limits concurrency. I suggest that you look at msdn.microsoft/library/system.threading.tasks.taskscheduler.aspx and search for LimitedConcurrencyLevelTaskScheduler.

下面的代码是您要实现的目标的简单示例.

The code below is a simple example of what you are trying to achieve.

[TestClass] public class UnitTest1 { [TestMethod] public async Task TestMethod1() { var factoryCancellation = new CancellationTokenSource(); var scheduler = new LimitedConcurrencyLevelTaskScheduler(maxDegreeOfParallelism: 7); var taskFactory = new TaskFactory(factoryCancellation.Token, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler); var taskCancellation1 = new CancellationTokenSource(); var taskCancellation2 = new CancellationTokenSource(); var token1 = taskCancellation1.Token; var token2 = taskCancellation2.Token; var myTask1 = taskFactory.StartNew(async () => await Execute(0, token1), token1).Unwrap(); var myTask2 = taskFactory.StartNew(async () => await Execute(1, token2), token2).Unwrap(); taskCancellation1.CancelAfter(500); try { await Task.WhenAll(myTask1, myTask2); } catch { //ThrowIfCancellationRequested Exception } } private async Task Execute(int i, CancellationToken token) { Console.WriteLine($"Running Task {i} : Before Delay 1"); await Task.Delay(1000); token.ThrowIfCancellationRequested(); Console.WriteLine($"Running Task {i} : Before Delay 2"); await Task.Delay(1000); token.ThrowIfCancellationRequested(); Console.WriteLine($"Running Task {i} : Before Delay 3"); await Task.Delay(1000); token.ThrowIfCancellationRequested(); } }

这将生成以下日志

QueueTask 1 WaitingToRun QueueTask 2 WaitingToRun TryExecuteTask Start 1 WaitingToRun CreationOptions None TryExecuteTask Start 2 WaitingToRun CreationOptions None Running Task 1 : Before Delay 1 Running Task 0 : Before Delay 1 TryExecuteTask End 2 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTask End 1 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTaskInline Start 5 taskWasPreviouslyQueued False TryExecuteTaskInline End 5 WaitingToRun IsCanceled False IsCompleted False IsFaulted False QueueTask 5 System.Action WaitingToRun TryExecuteTask Start 5 System.Action WaitingToRun CreationOptions None Running Task 1 : Before Delay 2 TryExecuteTask End 5 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTaskInline Start 6 taskWasPreviouslyQueued False TryExecuteTaskInline End 6 WaitingToRun IsCanceled False IsCompleted False IsFaulted False QueueTask 6 System.Action WaitingToRun TryExecuteTask Start 6 System.Action WaitingToRun CreationOptions None TryExecuteTaskInline Start 8 taskWasPreviouslyQueued False TryExecuteTaskInline End 8 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTask End 6 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTaskInline Start 12 taskWasPreviouslyQueued False TryExecuteTaskInline End 12 WaitingToRun IsCanceled False IsCompleted False IsFaulted False QueueTask 12 System.Action WaitingToRun TryExecuteTask Start 12 System.Action WaitingToRun CreationOptions None Running Task 1 : Before Delay 3 TryExecuteTask End 12 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTaskInline Start 14 taskWasPreviouslyQueued False TryExecuteTaskInline End 14 WaitingToRun IsCanceled False IsCompleted False IsFaulted False QueueTask 14 System.Action WaitingToRun TryExecuteTask Start 14 System.Action WaitingToRun CreationOptions None TryExecuteTaskInline Start 16 taskWasPreviouslyQueued False TryExecuteTaskInline End 16 RanToCompletion IsCanceled False IsCompleted True IsFaulted False TryExecuteTask End 14 RanToCompletion IsCanceled False IsCompleted True IsFaulted False

您可以看到任务0尽快被取消,任务1继续处理.此示例未显示,但绝不会超过7个并发任务.

You can see that the Task 0 is cancelled as soon as possible and Task 1 continue to process. This example does not show but will never be more than 7 concurrent tasks.

不幸的是,TAP模式不能与Scheduler的AttachToParent选项一起使用,否则此代码可能会更干净.请参阅:TaskCreationOptions.AttachedToParent不等待子任务

Unfortunately the TAP pattern does not works with the AttachToParent option of the Scheduler, or this code could be even more clean. See: TaskCreationOptions.AttachedToParent is not waiting for child task

要管理CancellationToken,您可以创建一个特定的TaskFactory来允许以下操作:

And to manage the CancellationTokens you can create a specific TaskFactory that allows something like this:

taskFactory.StartNew(0 , () => {...}); taskFactory.Cancel(0);

TaskFactory方法都不是虚拟的,因此您必须创建重载方法.

None of the TaskFactory methods are virtual so you will have to create overloaded method.

更多推荐

使用CancellationToken取消特定任务

本文发布于:2023-11-12 21:38:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1582592.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:CancellationToken

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!