当前位置: 首页 > news >正文

【C# 多线程】如何停止正在运行中的子线程

如何停止正在运行中的子线程

  • 通过协作式取消模式
  • 强制终止线程(可能存在资源不能及时释放的泄漏风险)

通过协作式取消模式

在线程函数中,你可以周期性地检查一个标志位,以确定是否应该停止线程。该标记位可以是共享变量,也可以是CancellationToken。

CancellationTokenSource 和 CancellationToken 被用来发送取消请求,而任务或线程通过检查 CancellationToken.IsCancellationRequested 属性或调用 ThrowIfCancellationRequested 方法来响应这个请求。

using System;  
using System.Threading;  
using System.Threading.Tasks; //
// 方式1:使用CancellationToken,停止标志位来停止线程
//
class CancellationTokenExample  
{  private CancellationTokenSource _cts = new CancellationTokenSource();  public void StartWork()  {  Task.Run(() =>  {  try  {  // 模拟长时间运行的工作,直到有取消请求时,退出while  while(!_cts.IsCancellationRequested) {  Thread.Sleep(1000); //如果有取消请求,也可以通过抛出异常结束线程_cts.Token.ThrowIfCancellationRequested();}  }  catch (OperationCanceledException)  {  //线程被取消  }  }, _cts.Token);  }  // 调用此函数来停止线程public void StopWork()  {  _cts.Cancel();  }  
}//
// 方式2:使用共享变量,停止标志位来停止线程
//
class ThreadStopExample  
{  // 停止标志  public volatile bool StopRequested { get; set; }  public void StartWork()  {  Task.Run(() =>  {  while (!StopRequested)  {   Thread.Sleep(1000); // 模拟工作  }  });  }  // 调用此函数来停止线程public void StopWork()  {  StopRequested = true;  }  
}

强制终止线程(可能存在资源不能及时释放的泄漏风险)

如果在线程中使用了一个内层的无限循环(while (true)),这将导致线程永远不会退出这个内层循环,此时要退出线程,除非执行强制停止。

using System;  
using System.Threading;  
using System.Threading.Tasks; class ForceExitCaseExample
{private CancellationTokenSource _cts;private Task task;public void StartWork(){//确保线程没有重复运行if (task == null || (task.IsCompleted || task.IsCanceled)){_cts = new CancellationTokenSource();task = Task.Run(() =>{//注册cancel时,执行Abort方法(不太行,偶尔报异常)//_cts.Token.Register(Thread.CurrentThread.Abort);//注册cancel时,执行Interrupt方法_cts.Token.Register(Thread.CurrentThread.Interrupt);try{bool workDone = false;//模拟长时间运行的工作Thread.Sleep(1000);Console.WriteLine("第一阶段工作完成...");//模拟条件长时间不满足,运行工作死循环while (!workDone){Console.WriteLine("第二阶段工作中...");Thread.Sleep(999);if (false){workDone = true;}}}catch (Exception ex){//线程被取消  Console.WriteLine($"线程异常结束:{ex.Message}");}}, _cts.Token);}}// 调用此函数来停止线程public void StopWork(){_cts.Cancel();}
}
http://www.lryc.cn/news/307861.html

相关文章:

  • 服务器机房安全守护:五大物理安全实践
  • spring boot 修复 Spring Framework URL解析不当漏洞(CVE-2024-22243)
  • VR全景HDR拍摄教程
  • hive执行select count(1)返回0
  • 3D Gaussian splatting 协方差矩阵 球谐函数 简单理解
  • 代码随想录算法刷题训练营day27:LeetCode(39)组合总和、LeetCode(40)组合总和 II、LeetCode(131)分割回文串
  • docker 容器修改端口和目录映射
  • echarts鼠标事件
  • 【北京迅为】《iTOP-3588开发板网络环境配置手册》第2章 电脑、开发板直连交换机或路由器
  • 6.5 共享数据
  • SpringBoot之Session新增、删除、获取配置与使用
  • Hive UDF 札记
  • npm已经配置淘宝源仍然无法使用
  • Qt5转Qt6笔记
  • FPGA高端项目:FPGA基于GS2971的SDI视频接收转HDMI输出,提供3套工程源码和技术支持
  • java 锁
  • 该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改。
  • Mybatis学习笔记:延迟加载
  • 蓝桥杯题练习:平地起高楼
  • 我愿意启动价值流
  • 排序算法1:冒泡排序、快速排序、插入排序
  • Vant Weapp
  • 无人机精准定位技术,GPS差分技术基础,RTK原理技术详解
  • java面试:elasticsearch
  • GO语言学习笔记(与Java的比较学习)(三)
  • 如何用Python3自撰一个简单的后端框架
  • 使用pyannote-audio实现声纹分割聚类
  • 防御保护:防火墙内容安全
  • uni-app webview 打开baidu.com
  • 【C#】SixLabors.ImageSharp和System.Drawing两者知多少