c# .netCreateLinkedTokenSource链接令牌,取消信号异步执行

cs 复制代码
// 心跳管理类
    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 的核心作用

  1. 令牌的隔离与组合

    • 将外部传入的 externalToken 与内部令牌源 _heartbeatCts 关联,形成 "链接令牌"
    • externalToken_heartbeatCts 任一被取消时,所有关联的操作都会收到取消信号
  2. 细粒度取消控制

    • 允许在不影响外部令牌的情况下,单独取消心跳服务(.NET 6+ 推荐方式):

      复制代码
      // 仅取消心跳服务,不影响AcceptClientsAsync
      _heartbeatCts.Cancel(); 
  3. 避免令牌源泄漏

    • 通过链接令牌,确保心跳服务能响应外部取消请求,同时保持自身的取消控制能力

二、关键实现原理csharp

复制代码
public void StartHeartbeatService(CancellationToken externalToken)
{
    // 创建与externalToken链接的新令牌源
    _heartbeatCts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
    
    // 使用_linkedToken控制心跳任务
    await CheckHeartbeatsAsync(_heartbeatCts.Token);
}
catch (OperationCanceledException)
{
    // 无论externalToken还是_heartbeatCts被取消,都会进入此分支
}

三、典型应用场景

  1. 主服务与子服务的取消关联

    • 主服务通过 externalToken 控制整体取消
    • 子服务(心跳检测)可独立取消,不影响其他服务
  2. 多组件协作取消

    • _heartbeatCts 被取消时,所有使用 _heartbeatCts.Token 的操作都会收到取消信号
    • 当外部 externalToken 被取消时,_heartbeatCts 也会自动取消

四、与直接使用 externalToken 的区别

场景 直接使用 externalToken 使用 CreateLinkedTokenSource
取消控制权 心跳服务无法主动取消 可独立取消心跳服务
外部影响 心跳服务取消会影响外部令牌 心跳服务取消不影响外部令牌
异常处理 难以区分取消来源 可通过令牌源区分取消来源

五、完整取消流程示例

  1. 主服务取消

    复制代码
    _cancellationTokenSource.Cancel(); // 外部令牌取消
    // 自动触发_heartbeatCts取消,心跳服务终止
  2. 心跳服务独立取消

    复制代码
    _heartbeatManager.StopHeartbeatService(); // 内部取消
    // _acceptTask仍可继续运行,不受影响
  3. 资源释放顺序

    主服务取消

    externalToken取消

    _heartbeatCts自动取消

    心跳任务终止

    释放心跳相关资源

六、最佳实践建议

  1. 明确取消范围

    • 使用 CreateLinkedTokenSource 时,始终确保:

      复制代码
      _heartbeatCts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);

      避免直接使用 externalToken 注册取消回调,防止意外影响主流程

  2. 异常处理优化

    复制代码
    try
    {
        await CheckHeartbeatsAsync(_heartbeatCts.Token);
    }
    catch (OperationCanceledException)
    {
        if (_heartbeatCts.IsCancellationRequested)
            Console.WriteLine("心跳服务主动取消");
        else
            Console.WriteLine("主服务取消导致心跳终止");
    }

    资源清理

复制代码
   public void Dispose()
   {
       _heartbeatCts?.Cancel();
       _heartbeatCts?.Dispose();
   }

通过 CreateLinkedTokenSource,您的心跳服务能够更灵活地响应取消请求,同时保持与主服务的取消关联,这是现代异步编程中处理复杂取消逻辑的最佳实践。

相关推荐
Chester_19996 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
EXI-小洲7 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员7 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导7 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan7 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251498 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
大衛說9 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
可乐鸡翅yeah_10 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线
2601_9622035110 小时前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理10 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php