C# Task Cancellation总结

本文探讨了CancellationToken的工作原理及其与Task之间的交互方式。详细分析了如何通过调用Cancel方法来请求取消Task,并介绍了如何利用ContinueWith方法根据不同执行结果(如完成、取消或异常)来指定后续操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、调用cancellationTokenSource.Cancel()时,只有在task的函数体内使用token.ThrowIfCancellationRequested()方法时才会触发ContinueWith(Action<Task>,TaskContinuationOptions.OnlyOnCanceled),且代理函数中taskExceptionnull,也就是说不会抛出异常;否则只会触发ContinueWith(Action<Task>,TaskContinuationOptions.OnlyOnRanToCompletion),且也不会抛出异常;


2、调用task.Wait()时,

1)当调用token.ThrowIfCancellationRequested()之后,如果有OnlyOnCanceled延续任务,则先执行延续任务,然后在task.Wait()中抛出AggregateException异常;


2)如果产生其他异常且有OnlyOnFaulted延续任务,则先执行延续任务,然后在task.Wait()中抛出异常;

3Task.ContinueWith方法的使用:

1public Task ContinueWith(Action<Task> continuationAction,TaskContinuationOptions continuationOptions);

2)函数的第一个参数是一个委托,其参数为执行ContinueWithTask实例,同时返回一个新的Task实例;

3)如果在实例化Task的时候连续调用ContinueWith函数,实例化出来的Task变量将是ContinueWith方法最后执行并返回的Task实例,同时,每一个ContinueWith函数将用于执行上一步ContinueWith函数返回的Task实例,而不是最初的Task实例;

4)在监听Task.Wait()时,如果有ContinueWith方法,要特别注意是哪个Task实例;

4、使用cancellationTokenSource后需要调用Dispose方法来释放其非托管资源;


5、调用cancellationTokenSource.Cancel()并不会终止task的执行,只是告知task取消的请求,如果不监听cancellationToken.IsCancellationRequested属性,或者不调用ThrowIfCancellationRequested方法,task将会一直执行;


### C#Task 的基本使用 #### 判断 Task 是否成功完成 在 C# 中,`Task` 是异步编程的核心组件之一。为了判断一个 `Task` 是否已经成功执行完毕,可以检查其状态属性 `Status`。如果该属性等于 `TaskStatus.RanToCompletion`,则表示此任务已正常结束而未发生任何错误或被取消。 ```csharp if (task.Status == TaskStatus.RanToCompletion) { Console.WriteLine("The task has successfully completed."); } ``` 上述代码片段展示了如何通过比较 `Task` 对象的状态来验证它是否顺利完成[^1]。 #### 创建并启动一个新的 Task 除了直接实例化 `Task` 并调用它的 `Start()` 方法外,还可以利用工厂模式下的静态方法更简便地创建与初始化新的线程任务。具体而言,可以通过 `Task.Factory.StartNew(Action action)` 来实现这一目的。 下面是一个简单的例子: ```csharp var myTask = Task.Factory.StartNew(() => { for(int i=0;i<5;i++) { Console.WriteLine($"Executing iteration {i}"); Thread.Sleep(100); } }); myTask.Wait(); Console.WriteLine("My Task is done!"); ``` 这里定义了一个匿名函数作为参数传递给 `StartNew` 方法,这个函数将在单独的任务中运行五次打印语句,并且每次之间暂停一百毫秒模拟工作负载。最后等待直到我的自定义任务完成后才继续主线程流程[^2]。 #### 取消正在运行中的 Task 当需要提前终止某些长时间运行的操作时,可以借助于 .NET 提供的 cancellation mechanism(取消机制)。这通常涉及到两个主要角色——`CancellationTokenSource` 和关联的 `CancellationToken` 实例。前者负责发出取消信号;后者嵌入目标逻辑内部以便监听外部变化情况进而采取适当行动比如中断当前进程或者释放资源等处理措施。 以下是从参考资料改编的一个实际应用案例说明了怎样安全有效地停止正在进行的工作单元: ```csharp static void DoWork(CancellationToken token) { try{ for (int i = 0; i < 10 && !token.IsCancellationRequested; i++) { // Check periodically whether a cancel request was made. token.ThrowIfCancellationRequested(); Console.WriteLine($"DoWork: Working on item #{i + 1}"); // Simulate work by sleeping the thread briefly. System.Threading.Thread.Sleep(500); } if (!token.IsCancellationRequested){ Console.WriteLine("All items processed."); } }catch(OperationCanceledException ex){ Console.WriteLine("Operation canceled before completion.",ex.Message); } } // Usage Example: public static async Task Main(string[] args){ var cts=new CancellationTokenSource(); _=Task.Run(()=>DoWork(cts.Token)); await Task.Delay(TimeSpan.FromSeconds(3)); // Let it run few iterations cts.Cancel(); // Request to stop further processing after some time. } ``` 在这个扩展版本里增加了异常捕获块用来妥善管理因主动触发退出而导致可能出现的预期之外状况的同时也保留原始功能不变即一旦接收到撤回指令立即响应不再做额外无谓尝试直至完全清理现场为止[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值