08-C#.Net-Thread-学习笔记

C#执行异步操作的几种方式总结比较 C#执行异步操作的几种方式总结比较 0x01 引言 之前写程序的时候在遇到一些比较花时间的操作例如HTTP请求时,总是会new一个Thread处理。对XxxxxAsync()之类的方法也没去了解过,倒也没遇到什么大问题。最近因为需求要求用DevExpress写界面,跑起来后发现比Native控件效率差好多。这才想到之前看到的“金科玉律”:不要在UI线程上执行界面无关的操作,因此集中看了下C#的 阅读详情

一、多线程基础概念

多线程的三大特点:

  • 异步执行:不阻塞主线程,多件事可以同时进行
  • 效率高:充分利用 CPU 等计算机资源
  • 无序性:多个线程的执行顺序不可预测,无法控制

⚠️ 正因为无序性,多线程调试困难,通常只能通过写日志、输出结果、结合线程 ID 来分析问题。

// 获取当前线程 ID,用于区分不同线程
int id = Thread.CurrentThread.ManagedThreadId;

二、Thread 类

基本概念

  • 来源:System.Threading 命名空间
  • 出现时间:.NET Framework 1.0
  • 类型:密封类(sealed class),不可被继承
  • 作用:操作计算机线程资源的帮助类库

开启线程

方式一:ThreadStart(无参数)

ThreadStart threadStart = new ThreadStart(() =>
{
    DoSomething("Richard");
});
Thread thread = new Thread(threadStart);
thread.Start();

方式二:ParameterizedThreadStart(带参数)

ParameterizedThreadStart pts = new ParameterizedThreadStart(obj =>
{
    Console.WriteLine($"参数: {obj}");
});
Thread thread = new Thread(pts);
thread.Start("传递的参数");

常用 API

线程控制
thread.Suspend();       // 暂停线程(不会立即停止)
thread.Resume();        // 恢复执行
thread.Abort();         // 停止线程(向线程抛出异常)
Thread.ResetAbort();    // 取消停止,让线程继续执行

❌ Suspend、Resume、Abort 均已标记为过时(Obsolete),实际开发中不应使用。线程无法真正从外部被强制终止,这些方法只是通过异常机制间接干预,存在安全隐患。

线程等待

方式一:观望式轮询(不推荐)

while (thread.ThreadState != ThreadState.Stopped)
{
    Thread.Sleep(500); // 每 500ms 检查一次
}

❌ 持续轮询会浪费 CPU 时间片,不推荐。

方式二:Join 等待(推荐)

thread.Join();                              // 无限等待,直到线程结束
thread.Join(500);                           // 最多等待 500ms,过时不候
thread.Join(TimeSpan.FromMilliseconds(500)); // 同上,TimeSpan 写法

✅ Join() 是最简洁直接的线程等待方式。

前台线程 vs 后台线程
thread.IsBackground = true;  // 后台线程:程序关闭时,线程立即终止
thread.IsBackground = false; // 前台线程:程序关闭时,等待线程执行完毕再退出
  • 默认:通过 new Thread() 创建的线程是前台线程
  • ThreadPool 中的线程全部是后台线程
  • 主线程(Main 方法所在线程)是前台线程

⚠️ 如果忘记将长时间运行的线程设为后台线程,可能导致程序关闭后进程仍然存活。

线程优先级
thread.Priority = ThreadPriority.Highest; // 最高优先级
thread.Priority = ThreadPriority.Lowest;  // 最低优先级

⚠️ 设置优先级只是提高被优先调度的概率,操作系统不保证严格按优先级执行,不能依赖它来控制执行顺序。


三、Thread 扩展封装

问题背景

多线程天然无序,但有时需要:

  1. 两个操作都在新线程中执行
  2. 同时保证它们的执行顺序

方案一:顺序执行两个委托

把两个委托放进同一个线程,天然保证顺序:

private void CallBackThread(ThreadStart threadStart, Action action)
{
    Thread thread = new Thread(() =>
    {
        threadStart.Invoke(); // 先执行
        action.Invoke();      // 后执行
    });
    thread.Start();
}

方案二:带返回值的异步执行

核心思路:立即开启新线程执行,返回一个"取结果的委托",调用方在需要结果时才触发等待。

private Func<T> CallBackFunc<T>(Func<T> func)
{
    T result = default;

    Thread thread = new Thread(() =>
    {
        result = func.Invoke(); // 新线程中执行
    });
    thread.Start(); // 立即开启,不阻塞

    // 返回一个延迟取值的委托
    return new Func<T>(() =>
    {
        thread.Join(); // 调用时才等待线程完成
        return result;
    });
}

使用示例:

Func<int> asyncFunc = CallBackFunc(() =>
{
    Thread.Sleep(5000);
    return DateTime.Now.Year;
});

// 这里不阻塞,可以继续做其他事
Console.WriteLine("继续执行其他任务...");

// 需要结果时才等待
int result = asyncFunc.Invoke();

⚠️ .NET Core 中 Delegate.BeginInvoke / EndInvoke 已不再支持,不能用于异步执行委托,需要用上述方式或 Task 替代。


四、ThreadPool 线程池

为什么需要线程池

Thread 的问题:

  • API 繁多,控制复杂
  • 线程数量需要程序员手动管理,容易滥用
  • 频繁创建/销毁线程,系统开销大

ThreadPool 的优势:

  • .NET Framework 2.0 引入,采用池化思想
  • 预先创建线程放入池中,需要时直接取用,用完自动归还
  • 自动管理线程数量,防止资源耗尽
  • API 更简洁,去掉了 Thread 中不必要的方法

申请线程执行任务

ThreadPool.QueueUserWorkItem(obj =>
{
    DoSomething(obj.ToString());
}, "参数");

线程等待:ManualResetEvent

ThreadPool 没有 Join(),需要用 ManualResetEvent 实现等待。

ManualResetEvent resetEvent = new ManualResetEvent(false); // 初始为未触发

ThreadPool.QueueUserWorkItem(obj =>
{
    DoSomething(obj.ToString());
    resetEvent.Set(); // 任务完成,发出信号
}, "Richard");

// 主线程可以继续做其他事
Console.WriteLine("主线程继续执行...");

resetEvent.WaitOne(); // 阻塞,直到 Set() 被调用
Console.WriteLine("子线程已完成");

工作原理:

  1. new ManualResetEvent(false) — 初始状态为"未触发"
  2. 子线程任务完成后调用 Set() — 状态变为"已触发"
  3. 主线程调用 WaitOne() — 阻塞等待,直到状态变为"已触发"才继续

控制线程数量

ThreadPool.SetMinThreads(4, 4); // 设置最小工作线程数和 IO 线程数
ThreadPool.SetMaxThreads(8, 8); // 设置最大工作线程数和 IO 线程数

ThreadPool.GetMinThreads(out int minWorker, out int minIO);
ThreadPool.GetMaxThreads(out int maxWorker, out int maxIO);
  • 第一个参数:工作线程数(Worker Threads),用于 CPU 密集型任务
  • 第二个参数:IO 线程数(Completion Port Threads),用于 IO 操作

❌ 强烈不建议手动设置线程池大小。原因:

  • 这是进程级别的全局设置
  • Task、Parallel、async/await 底层都使用线程池,修改后会影响所有这些功能
  • 设置不当容易引发性能问题甚至死锁

五、Thread vs ThreadPool 对比

特性ThreadThreadPool
出现时间.NET 1.0.NET 2.0
线程管理手动创建和销毁自动管理,复用线程
API 复杂度复杂,功能多简单,易用
性能频繁创建销毁,开销大复用线程,性能好
线程等待Join()ManualResetEvent
默认线程类型前台线程后台线程
适用场景需要精细控制的长时间任务大量短时间并发任务

六、注意事项与最佳实践

✅ 短时间任务优先使用 ThreadPool
✅ 使用 Join() 进行 Thread 的线程等待
✅ 使用 ManualResetEvent 进行 ThreadPool 的线程同步
✅ 长时间运行的线程记得设置 IsBackground = true
❌ 避免使用 Abort()、Suspend()、Resume()
❌ 不要手动设置线程池大小
❌ 不要在生产环境依赖线程优先级来控制执行顺序

⚠️ 多个线程访问共享资源时需要加锁(lock、Monitor 等),否则会出现数据竞争问题。
⚠️ 线程内部的异常不会自动传播到主线程,必须在线程内部自行处理。
⚠️ 在实际项目中,更推荐使用 Task 和 async/await,它们是对线程池的更高层封装,代码更简洁,异常处理和取消机制也更完善。

.NET深度解析:从C#特性到运行时原理的技术人格实践 .NET作为微软主导的跨平台开发框架,其核心价值不仅在于语法糖与API封装,更体现在编译器契约、运行时行为与开发者工程决策的深度耦合。理解C#语言特性(如required成员、primary constructors)必须回溯至IL指令生成、JIT编译逻辑与CoreCLR源码实现;掌握Span<T>、IAsyncEnumerable<T>等高性能类型,需穿透到内存布局、线程安全模型与GC交互机制。这种‘代码—编译—运行’三位一体的认知体系,构成了.NET技术深度的核心支柱,支撑着高并发、低延迟、强一致性的企 阅读详情

相关推荐

从零构建生产级K8s-v1.35.0集群:基于Containerd与Cilium的kubeadm实战指南

本文详细介绍了从零构建生产级K8s-v1.35.0集群的全过程,涵盖环境准备、Containerd配置、Kubernetes组件安装、集群初始化及Cilium网络部署等关键步骤。通过实战经验分享系统调优技巧和常见问题解决方案,帮助读者快速搭建稳定高效的Kubernetes集群。

weixin_28725553的博客 218

C# Thread类的应用

C# Thread类的应用http://developer.51cto.com/art/200908/141590.htmhttp://developer.51cto.com  2009-08-04 17:08  yizhiduxiu11  csdn  我要评论(2) 本文开始C#线程系列讲座之二,即Thread类的应用。C# Thread类可以开始一个新的进程,并实现静态或实例方法。  C#自定义特性介绍C#内置特性介绍如何进行C#异常类的自定义C#编程技巧七条预测C#与.NET的发展趋势<br />

rise51的专栏 693

别再手动配IP了!保姆级教程:用Cisco Packet Tracer搞定DHCP服务器配置(附实验抓包分析)

本文提供了一份详细的Cisco Packet Tracer DHCP服务器配置教程,帮助用户告别手动分配IP的繁琐过程。通过构建多子网实验环境,逐步指导DHCP地址池设置、客户端测试及协议分析,并分享常见问题排查技巧,让网络配置更高效、更智能。

weixin_42535461的博客 336

.NET周刊【8月第4期 2024-08-25】

本文介绍了在Windows 10和Windows 11系统中使用亚克力和Mica等材质特效的方法。详细讲解了不同API的使用方式及其特性,如SetWindowCompositionAttribute和SetWindowAttribute。在实际操作中,需设置AllowTransparency,但可能存在鼠标穿透和性能问题。通过调用HwndSource和DwmExtendFrameIntoClientArea等方法解决这些问题。

InCerry的博客 930

MT6816角度传感器SPI通信避坑指南:从数据手册到稳定读取的3个关键步骤

本文详细解析了MT6816角度传感器SPI通信中的常见问题与解决方案,包括寄存器地址计算、SPI时序配置和数据校验等关键步骤。通过实测波形和代码示例,帮助工程师避开数据手册中的隐藏陷阱,实现稳定可靠的角度数据读取,特别适用于高精度电机控制场景。

weixin_42520573的博客 516

Holtek BS45F3833芯片深度剖析:如何用高集成MCU重塑超声波雾化市场格局?

本文深度剖析Holtek BS45F3833芯片如何通过高集成MCU技术重塑超声波雾化市场。该芯片集成了PWM直驱、电容检水、触摸控制等核心功能,显著提升雾化精度和效率,同时降低BOM成本和开发难度。文章通过实测数据和实战案例,展示了其在香薰机、车载设备及工业加湿器等场景的创新应用,为开发者提供了一站式解决方案。

weixin_29192211的博客 409

08-C#

线程无法真正从外部被强制终止,这些方法只是通过异常机制间接干预,存在安全隐患。⚠️ 正因为无序性,多线程调试困难,通常只能通过写日志、输出结果、结合线程 ID 来分析问题。⚠️ 如果忘记将长时间运行的线程设为后台线程,可能导致程序关闭后进程仍然存活。:立即开启新线程执行,返回一个"取结果的委托",调用方在需要结果时才触发等待。,它们是对线程池的更高层封装,代码更简洁,异常处理和取消机制也更完善。,操作系统不保证严格按优先级执行,不能依赖它来控制执行顺序。已不再支持,不能用于异步执行委托,需要用上述方式或。

噢~ 370

Python爬虫技术:使用Playwright和Twitter API v2高效获取Twitter/X数据完全教程

遵守规则:始终遵循Twitter的使用条款和速率限制错误处理:实现完善的错误处理和重试机制数据质量:进行数据清洗和验证性能优化:使用异步处理和合理的延迟设置可维护性:模块化代码,便于维护和扩展。

2201_76125261的博客 671

C#学习笔记之四(Attribute, Reflection, Thread, Thread Syn

<!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--><script type="text/javascript"

zgqtxwd的专栏 708

简要介绍 | 雷达穿墙成像及其应用场景

本文简要介绍了雷达穿墙成像技术的原理、研究现状、挑战与未来展望,希望能为相关领域的研究与应用提供参考。具有广泛的应用前景。本文将详细介绍雷达穿墙成像的原理,以及其在不同应用场景中的实践。逆时偏移算法(Reverse-Time Migration, RTM)雷达穿墙成像技术是一种先进的遥感技术,具有。的能力,可用于探测室内目标。安全与救援、建筑结构检测等领域。雷达穿墙成像技术的核心原理是。是Green函数,表示从接收点。雷达穿墙成像及其应用场景。雷达穿墙成像及其应用场景。目标识别与定位准确性。

NLOS的博客 2232

PCIe 全解析笔记:从协议本质到工程实现

学习 PCIe,最容易陷入的误区是直接跳进协议手册(Base Spec 1300 多页),然后在 TLP 字段、LTSSM 状态、Ordering Rules 中迷失方向。正确的思维路径历史维度:从 PCI 到 PCIe,解决了什么核心矛盾?抽象维度:协议栈分层的真正意图是什么?工程维度:高速串行链路面临哪些物理挑战?协议如何应对?系统维度:作为 CPU 与外设的"动脉",PCIe 如何融入整个计算机体系?带着这四个视角去看每一个细节,知识才能内化为认知。

m0_46644103的博客 261

CH08_多线程

当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件等。Thread类是是控制线程的基础类,位于System.Threading命名空间下,具有4个重载的构造函数:1、编写线程所要执行的方法2

赋能智能制造,驱动人才未来! 818

Trustzone/TEE/安全 面试100问-目录

关键词:cache学习、mmu学习、cache资料、mmu资料、arm资料、armv8资料、armv9资料、 trustzone视频、tee视频、ATF视频、secureboot视频、安全启动视频、selinux视频,cache视频、mmu视频,armv8视频、armv9视频、FF-A视频、密码学视频、RME/CCA视频、学习资料下载、免费学习资料、免费 周贺贺,baron,代码改变世界ctw,Arm精选, 资深安全架构专家,十年手机安全/SOC底层安全开发经验。擅长trustzone/tee安全产品的设计

baron-周贺贺-代码改变世界ctw 649

.Net开发中的多线程编程-文章

微软.Net开发中的多线程编程文章,在www.webjx.com上搜索到的。http://www.webjx.com/search.php?type=title&keywords=%B6%E0%CF%DF%B3%CCVB.Net-C#多线程Thread-代理委托delegate编程 1、微软.Net开发中的多线程编程总结2007-10-152、Visual C#多线程参

VB.Net+Android.java 1619

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【C#】ThreadPool的使用

【C#】ThreadPool的使用

wangnaisheng的专栏 1159

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

微软技术周报 · 2026-08-11~2026-08-18

微软本周技术动态聚焦两大方向:AI体验整合与安全更新。AI方面,Copilot统一入口copilot.cloud.microsoft上线,Foundry Agent框架GA,MAI模型家族完成5线整合;开发者工具上,C# 14正式支持扩展成员、field关键字等特性,.NET 11 Preview 7优化异步分层编译和WASM支持。安全侧发布8月补丁日,修复421个CVE(含1个Lazarus组织利用的零日漏洞)。其他亮点包括VS Code接入MAI-Voice、Power Platform现代控件GA、T

海盗Sharp的博客 821

【转】异步编程系列(Thread、Task、async/await、ajax等)

序 经过一番努力,我写的异步编程系列也算有头有尾,当然不是说这个系列已经更新完毕,这个头尾只是表示新旧知识点都有简单涉及到,接下去我还会丰富这一系列并且有机会整个小应用(愿景是弄一个开源组件吧,结合socket)。 术语: APM    异步编程模型,Asynchronous Programming Model EAP    基于事件的异步编程模式,Event-based Asynchronous Pattern TAP    基于任务的异步编程模式,Task-based As...

sinolover的专栏 618

C#多线程并发编程深度探索:解锁async、await、Task与lock等关键字的奥秘

多线程是指在一个应用程序中同时执行多个线程的能力。每个线程都是独立运行的,拥有自己的执行路径和资源。多线程编程能够充分利用多核处理器的计算能力,提高应用程序的性能和响应性,特别是在处理耗时任务和并行计算时效果显著。在C#中,线程是程序执行流的最小单元,每个线程都拥有独立的执行栈、程序计数器和本地变量。多线程编程允许程序同时执行多个线程,从而实现并发执行,提高程序的执行效率。

weixin_67244432的博客 1911

C# async 和 await

.NET 中的 async/await 异步编程 2015/04/08 ·IT技术·.Net,异步编程 分享到:3 python正则表达式 React入门 走进大数据之storm流式计算基础 Shell典型应用之系统信息及运行状态获取 原文出处:Teroy 的博客欢迎分享原创到伯乐头条 前言 最近在学习Web Api框...

weixin_30258027的博客 399

c#Task、Thread、线程、进程、线程池

NET Framework2.0时代,出现了一个线程池ThreadPool,是一种池化思想,如果需要使用线程,就可以直接到线程池中去获取直接使用,如果使用完毕,在自动的回放到线程池去;多线程是指程序中包含多个执行流(线程),即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。线程不能独立运行,必须包含在进程中。Task在.net 4.0时出现,是在线程池基础上封装而来的,提供了对线程的延续,取消,等待,超时等方面功能。异步不一定是多线程。

yoyo21ktime的博客 3243

333 Main Thread

Main Thread

医药/LIMS实验室IT · Office自动化 · .NET+Vue全栈 · 鸿蒙实战 · 欢迎技术交流 324

NET FrameWork & CLR & C# 运行基本原理

CLR 管理TOOLS: 1)(推荐) CLR Profiler (Allocation Profiler)来诊断内存泄露;微软公司提供,免费. 2) (推荐) ANTS Profiler: 可以对桌面和网络应用提供解析,最新的版本据说可以支持Windows Vista。 DevPartner 性能分析软件: 能够支持.NET,也能支持过去的COM, ...

weixin_33889245的博客 99

c#程序设定使用期限_C# 给某个方法设定执行超时时间

在某些情况下(例如通过网络访问数据),常常不希望程序卡住而占用太多时间以至于造成界面假死。在这时、我们可以通过Thread、Thread + Invoke(UI)或者是 delegate.BeginInvoke 来避免界面假死,但是这样做时,某些代码或者是某个方法的执行超时的时间还是无法操控的。那么我们又是否有一种比较通用的方法、来设定某一个方法的执行超时的时间,让其一旦超过指定时间则跳出指定方法...

weixin_39571179的博客 739

C# 跨线程操作控件

01.using System; 02.using System.Collections.Generic; 03.using System.ComponentModel; 04.using System.Data; 05.using System.Drawing; 06.using System.Text; 07.using System.Windows.Forms; 08.using Sys

u010484683的专栏 931

人生低谷来撸C#--021 多线程

在C#中,多线程是指在一个应用程序中同时运行多个线程的能力。每个线程代表一个独立的执行路径,可以在同一进程内并发执行。到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。多线程编程中的一个重要问题是线程同步,即确保多个线程不会同时访问或修改共享资源,从而避免竞态条件和其他并发问题。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。

weixin_41104586的博客 1116

java currenthread_currentThread

.NET简谈组件程序设计之(初识.NET线程Thread)由于多线程的内容比较多我会用几篇文章来讲解。多线程在我们日常开发过程中用的很多,上一篇“.NET简谈组件程序设计之(异步委托) ”详细的讲解了基于委托的多线程使用,委托是基于后台线程池的原理,这篇文章将主要介绍直接使用Thread对象来实现多线程。当然使用Thread没有使用Delegate那...文章王清培2011-08-27698浏览量...

weixin_39782545的博客 256
上一篇: 07-C#.Net-数据结构-学习笔记
下一篇: 09-C#.Net-多线程-基础篇-学习笔记
似水明俊德
博客等级 码龄8年 247粉丝 276原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值