-
C#多线程精解:优雅终止线程的实用方法与技巧
概述:在C#多线程编程中,合理终止线程是关键挑战。通过标志位或CancellationToken,实现安全、协作式的线程终止,确保在适当时机终止线程而避免资源泄漏。
应用场景:
在C#多线程编程中,有时需要终止正在运行的线程,例如在用户取消操作、程序关闭等情况下。
思路:
线程终止通常涉及到合作式终止而非强制终止,因为强制终止可能导致资源泄漏和不确定的状态。一般采用标志位、信号等方式,让线程自行安全地退出。
方法和步骤:
1.使用标志位控制线程执行:
using System;
using System.Threading;
public class Worker
{
// 标志位,用于控制线程执行
private volatile bool shouldStop = false;
public void DoWork()
{
while (!shouldStop)
{
// 线程执行的工作
Console.WriteLine("Working...");
Thread.Sleep(1000); // 模拟工作
}
}
// 设置标志位,终止线程
public void StopWork()
{
shouldStop = true;
}
}
public class Program
{
public static void Main()
{
Worker worker = new Worker();
// 启动线程执行工作
Thread thread = new Thread(worker.DoWork);
thread.Start();
// 模拟运行一段时间后,终止线程
Thread.Sleep(5000);
worker.StopWork();
// 等待线程结束
thread.Join();
Console.WriteLine("Thread stopped.");
}
}
上述代码中,通过设置shouldStop标志位,线程在下一个循环中检查到标志位为true时自动退出。
2.使用CancellationToken终止线程:
using System;
using System.Threading;
public class Worker
{
// CancellationTokenSource用于生成CancellationToken
private CancellationTokenSource cts = new CancellationTokenSource();
public void DoWork()
{
CancellationToken token = cts.Token;
while (!token.IsCancellationRequested)
{
// 线程执行的工作
Console.WriteLine("Working...");
Thread.Sleep(1000); // 模拟工作
}
}
// 使用CancellationToken请求终止线程
public void StopWork()
{
cts.Cancel();
}
}
public class Program
{
public static void Main()
{
Worker worker = new Worker();
// 启动线程执行工作
Thread thread = new Thread(worker.DoWork);
thread.Start();
// 模拟运行一段时间后,终止线程
Thread.Sleep(5000);
worker.StopWork();
// 等待线程结束
thread.Join();
Console.WriteLine("Thread stopped.");
}
}
上述代码中,通过CancellationToken及其关联的CancellationTokenSource,在StopWork方法中调用Cancel方法通知线程终止。
在实际应用中,需要根据具体场景选择合适的终止线程的方式,并确保线程能够在终止时完成清理工作
来源:https://www.cnblogs.com/hanbing81868164/p/18018739
栏目列表
最新更新
springboot3.0整合mybatis-flex实现逆向工程的示
SpringBoot使用MyBatis-Flex实现灵活的数据库访
RedisTemplate.opsForHash()用法简介并举例说明
mybatis-flex实现链式操作的示例代码
mybatis-flex实现多数据源操作
MyBatis-Flex实现多表联查(自动映射)
在Spring Boot中处理文件上传功能实现
Java中处理XML数据的方法
SpringBoot使用spring.factories加载默认配置的
Java解析微信获取手机号信息的示例步骤
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比