Task 很优雅的取消方式是什么?C# 里面。

C# 里取消 Task 的正规做法是协作式取消:调用方拿 `CancellationTokenSource` 发出取消,任务内部用 `CancellationToken` 在安全的检查点自己停下来。不要用 `Thread.Abort`,也不要靠 `Dispose` 任务来取消。

怎么写

调用方创建取消源,把 Token 传进任务,需要停的时候调用 `Cancel()`,然后仍然 `await` 这个任务,让它做完收尾。

```csharp

using var cts = new CancellationTokenSource();

try

{

await RunAsync(cts.Token);

}

catch (OperationCanceledException)

{

// 这是取消,不是故障

}

void Stop() => cts.Cancel();

async Task RunAsync(CancellationToken ct)

{

while (true)

{

ct.ThrowIfCancellationRequested();

await DoOneStepAsync(ct); // 支持 Token 的 API 把 Token 继续传下去

await Task.Delay(10, ct);

}

}

```

`ThrowIfCancellationRequested()` 会抛出 `OperationCanceledException`。捕获它表示「被人停了」;别的异常才是失败。取消之后不要把流程记成成功。

为什么说它优雅

`Cancel()` 只是把标记设为已取消,不会把线程掐死。任务跑到下一次检查 Token 的地方才停,所以不会停在写到一半的串口帧或运动指令中间。

支持 Token 的 API 会自己停:`Task.Delay`、`ReadAsync`、`WaitAsync`、`Task.Run` 的重载。Token 要一路传到最底层,传断了,底层仍会把当前这次 IO 做完。

超时和停止按钮可以合成一个 Token:

```csharp

using var stopCts = new CancellationTokenSource();

using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(30));

using var linked = CancellationTokenSource.CreateLinkedTokenSource(

stopCts.Token, timeoutCts.Token);

await MoveAndWaitAsync(linked.Token);

```

任一来源取消,任务都会看到。`CancelAfter` 则是同一个源上的超时。

收尾不要写在 `catch` 里碰运气。用 `finally`,或者 `token.Register(() => StopAxis())`,保证取消时能发减速停。`Register` 的回调可能跑在任意线程上,里面不要动 UI 控件。

上位机里怎么用

自动流程的等待循环带着 Token。停止按钮调用 `Cancel()`。通信线程在下一次检查时看到取消,再调用 `dmc_stop` 或写 PLC 停机位,然后抛出取消异常,状态机进入「已停止」。不要在 UI 线程里 `while` 等运动完成,也不要 `Abort` 那条正在调运动卡的线程。

相关推荐
码农小河662 小时前
基于PHP的电商后台蜜罐系统
开发语言·php
starzy19902 小时前
深入理解Scala柯里化函数:函数链式变换
开发语言·scala
ShineWinsu2 小时前
对于Qt:QTreeWidget常见属性以及QTreeWidgetItem类的解析
开发语言·c++·qt·gui·客户端·多叉树·qtreewidget
落羽的落羽3 小时前
【C++】C++17的主要特性
linux·服务器·开发语言·c++·算法·机器学习
总要学点什么3 小时前
第108篇:三维特效-图片轨迹线效果——把贴图滚成一串箭头,想用它的本色反而整条消失
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
暴走约伯6 小时前
【VFX工具链源码拆解 09】终极工业化闭环:基于 ID 规则驱动的全自动场景建档、骨骼挂载与男转女场景迁移
unity·c#·游戏引擎·材质
starzy19908 小时前
深入理解Scala隐式值:编译期自动装配
开发语言·后端·scala
布莱克6058 小时前
Swift 条件语句详解:从 if 到 switch 的完整指南
开发语言·ssh·swift·switch·条件语句·guard·if
吴可可1238 小时前
ActiveX调用WScript.Shell原理揭秘
开发语言
晴天的雨.9929 小时前
【C++】继承篇
java·开发语言·c++