c# .netCreateLinkedTokenSource链接令牌,取消信号异步执行
// 心跳管理类public class WebSocketHeartbeatManager{
websocketserver.cs
_cancellationTokenSource = new CancellationTokenSource();var token = _cancellationTokenSource.Token;_heartbeatManager.StartHeartbeatService(token);_acceptTask = AcceptClientsAsync(token); //log5:websocket服务端,检测客户端连接websocketserver的主类中创建的CancellationTokenSource
public void StartHeartbeatService(CancellationToken externalToken)
{_heartbeatCts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
CreateLinkedTokenSource是什么作用
CancellationTokenSource.CreateLinkedTokenSource
方法用于创建一个与外部令牌关联的新令牌源,它在您的 WebSocket 服务中主要解决以下问题:
一、CreateLinkedTokenSource 的核心作用
-
令牌的隔离与组合
- 将外部传入的
externalToken
与内部令牌源_heartbeatCts
关联,形成 "链接令牌" - 当
externalToken
或_heartbeatCts
任一被取消时,所有关联的操作都会收到取消信号
- 将外部传入的
-
细粒度取消控制
- 允许在不影响外部令牌的情况下,单独取消心跳服务(.NET 6+ 推荐方式):
// 仅取消心跳服务,不影响AcceptClientsAsync _heartbeatCts.Cancel();
- 允许在不影响外部令牌的情况下,单独取消心跳服务(.NET 6+ 推荐方式):
-
避免令牌源泄漏
- 通过链接令牌,确保心跳服务能响应外部取消请求,同时保持自身的取消控制能力
二、关键实现原理csharp
public void StartHeartbeatService(CancellationToken externalToken)
{// 创建与externalToken链接的新令牌源_heartbeatCts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);// 使用_linkedToken控制心跳任务await CheckHeartbeatsAsync(_heartbeatCts.Token);
}
catch (OperationCanceledException)
{// 无论externalToken还是_heartbeatCts被取消,都会进入此分支
}
三、典型应用场景
-
主服务与子服务的取消关联
- 主服务通过
externalToken
控制整体取消 - 子服务(心跳检测)可独立取消,不影响其他服务
- 主服务通过
-
多组件协作取消
- 当
_heartbeatCts
被取消时,所有使用_heartbeatCts.Token
的操作都会收到取消信号 - 当外部
externalToken
被取消时,_heartbeatCts
也会自动取消
- 当
四、与直接使用 externalToken 的区别
场景 | 直接使用 externalToken | 使用 CreateLinkedTokenSource |
---|---|---|
取消控制权 | 心跳服务无法主动取消 | 可独立取消心跳服务 |
外部影响 | 心跳服务取消会影响外部令牌 | 心跳服务取消不影响外部令牌 |
异常处理 | 难以区分取消来源 | 可通过令牌源区分取消来源 |
五、完整取消流程示例
-
主服务取消
_cancellationTokenSource.Cancel(); // 外部令牌取消 // 自动触发_heartbeatCts取消,心跳服务终止
-
心跳服务独立取消
_heartbeatManager.StopHeartbeatService(); // 内部取消 // _acceptTask仍可继续运行,不受影响
-
资源释放顺序
主服务取消
externalToken取消
_heartbeatCts自动取消
心跳任务终止
释放心跳相关资源
六、最佳实践建议
-
明确取消范围
- 使用
CreateLinkedTokenSource
时,始终确保:_heartbeatCts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
避免直接使用
externalToken
注册取消回调,防止意外影响主流程
- 使用
-
异常处理优化
try {await CheckHeartbeatsAsync(_heartbeatCts.Token); } catch (OperationCanceledException) {if (_heartbeatCts.IsCancellationRequested)Console.WriteLine("心跳服务主动取消");elseConsole.WriteLine("主服务取消导致心跳终止"); }
资源清理
-
public void Dispose() {_heartbeatCts?.Cancel();_heartbeatCts?.Dispose(); }
通过 CreateLinkedTokenSource
,您的心跳服务能够更灵活地响应取消请求,同时保持与主服务的取消关联,这是现代异步编程中处理复杂取消逻辑的最佳实践。