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

30. 异步和多线程

1.异步和多线程简介

2.IOCP

3.await后代码执行的线程


1.异步和多线程简介

a.多线程:像是你同时请了多个工人(线程)干活,每个工人独立执行自己的任务,CPU需要在这些工人之间切换调度;这是并 发执行的一种实现方式 b.异步:是一种编程模式/思想,核心是"非阻塞"—— 当遇到耗时操作(比如:IO、网络请求),当前线程不会傻等,而是去 处理其他任务,等耗时操作完成后再回来处理结果;异步不一定需要创建新线程

1).IO密集型 最典型的就是"文件读写, 数据库操作, 网络请求",这类操作的耗时主要花在等待外部设备(硬盘/网络)响应,而非占用 CPU;C#的异步在处理这类操作时,底层会利用"操作系统的IOCP(IO完成端口)机制, 不会创建新线程"
usingSystem;usingSystem.IO;usingSystem.Threading.Tasks;classProgram{staticasyncTaskMain(){// 异步读取文件(IO密集型)stringcontent=awaitReadFileAsync("test.txt");Console.WriteLine(content);}staticasyncTask<string>ReadFileAsync(stringpath){// await执行时,当前线程会返回线程池,去处理其他任务// 文件读取完成后,系统会通知CLR,再从线程池取一个线程继续执行后续代码// 全程没有创建新线程,只是复用了线程池的线程using(varreader=newStreamReader(path)){returnawaitreader.ReadToEndAsync();}}}

2).CPU密集型 如果异步方法里执行的是CPU密集型任务(比如复杂计算),此时异步需要依赖多线程才能实现非阻塞
usingSystem;usingSystem.Threading;usingSystem.Threading.Tasks;classProgram{staticvoidMain(){// new Thread:新建操作系统线程(不在线程池)newThread(()=>{// 打印线程ID+是否线程池线程(结果:否)Console.WriteLine($"new Thread线程ID:{Thread.CurrentThread.ManagedThreadId},是否线程池:{Thread.CurrentThread.IsThreadPoolThread}");}).Start();Console.ReadKey();}}

2.IOCP

IOCP就是操作系统为程序提供的一个"异步I/O结果通知中心",程序把I/O请求交给操作系统后就可以去干别的事,等I/O操作 完成了,操作系统会通过这个"通知中心"告诉程序"你的请求做完了, 来拿结果吧"
当你在C#中写awaitreader.ReadToEndAsync(),底层流程是这样的 a.你的C#程序调用.NET 类库的异步方法,.NET会把"读取文件"这个IO请求交给Windows操作系统 b.操作系统把这个请求加入IOCP的"待处理队列",然后立刻告诉你的C#程序"请求已提交",你可以先回去干活了 c.当硬盘完成文件读取后,操作系统会把"读取完成"的结果放到IOCP的"完成队列"里 d.".NET的CLR"会监控这个IOCP完成队列,发现有完成的请求后,从线程池取一个空闲线程,继续执行await后面的代码,比 如打印文件内容 整个过程中,没有为这个IO请求创建新线程,只有IO完成后才短暂占用一个线程处理结果,这就是异步IO比多线程处理IO高 效的根本原因,而IOCP就是实现这个流程的核心机制

3.await后代码执行的线程

await后代码的执行线程,不是绝对由线程池决定,而是由await执行前当前线程的"同步上下文"决定 a.控制台:无特殊同步上下文,"await后代码在线程池线程执行"
usingSystem;usingSystem.IO;usingSystem.Threading;usingSystem.Threading.Tasks;classProgram{staticasyncTaskMain(){// 打印主线程信息(控制台主线程不是线程池线程)Console.WriteLine($"主线程ID:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread}");// 异步读取文件(IO操作,释放主线程)stringcontent=awaitReadFileAsync("test.txt");// 打印await后的线程信息(此时是线程池线程)Console.WriteLine($"await后线程ID:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread}");Console.WriteLine(content);}staticasyncTask<string>ReadFileAsync(stringpath){// 确保文件存在(先创建一个测试文件)if(!File.Exists(path))awaitFile.WriteAllTextAsync(path,"测试IOCP异步读取");using(varreader=newStreamReader(path)){returnawaitreader.ReadToEndAsync();// IOCP处理的核心异步点}}}

b.UI程序:WinForm/WPF,"有UI同步上下文, await后代码会回到原UI主线程"
// 新建WinForm项目,在Form1中添加一个按钮Button1usingSystem;usingSystem.IO;usingSystem.Threading;usingSystem.Windows.Forms;publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privateasyncvoidButton1_Click(objectsender,EventArgse){// 打印UI主线程信息(非线程池线程)MessageBox.Show($"点击按钮的线程ID:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread}");// 异步读取文件stringcontent=awaitFile.ReadAllTextAsync("test.txt");// 打印await后的线程信息(还是原UI主线程)MessageBox.Show($"await后线程ID:{Thread.CurrentThread.ManagedThreadId},是否线程池线程:{Thread.CurrentThread.IsThreadPoolThread}");// 直接更新UI控件(无跨线程异常,因为回到了UI线程)label1.Text=content;}}

c."unity中await后代码会回到主线程"
usingUnityEngine;usingUnityEngine.UI;usingSystem.Threading.Tasks;publicclassAsyncLoadAwaitExample:MonoBehaviour{publicTexttipText;privateasyncvoidStart(){Debug.Log($"Start方法线程ID:{System.Threading.Thread.CurrentThread.ManagedThreadId}");// 异步加载资源,await后自动回主线程varresourceRequest=Resources.LoadAsync<Sprite>("Images/player");awaitresourceRequest;// 打印await后的线程ID(和主线程一致)Debug.Log($"await后线程ID:{System.Threading.Thread.CurrentThread.ManagedThreadId}");// 直接操作UISpritesprite=(Sprite)resourceRequest.asset;tipText.text="Await加载完成";}}
http://www.jsqmd.com/news/349061/

相关文章:

  • 唐山有哪些信誉好的GEO优化公司推荐 - 工业设备
  • 2026年质量好的四川柴油发电机供应商最新推荐权威榜 - 朴素的承诺
  • 2026年正规的CIFF上海潮向生活美学展,CIFF上海都市户外展,CIFF海软体家居技术展公司采购优选榜单 - 品牌鉴赏师
  • java+vue基于springboot的汽车路试数据管理系统设计与实现_9859us78
  • GD32F103C8T6每个引脚介绍和整理
  • 【EI Compendex、Scopus检索】第二届智慧城市与可持续发展国际学术会议(SCSD 2026)
  • Excel时间差计算技巧解析
  • SEW变频器MCS40A0075-2A3-4-00 08270759
  • 2026年贵州不锈钢螺旋筋瓦斯管加工厂口碑排名,哪家售后好? - myqiye
  • java+vue基于springboot的婚庆服务平台的功能设计_5qtr5245
  • SEW变频器MCS40A0150-203-4-00 08273057
  • 天津福森印前做包装盒设计开发打样定制费用多少,值得推荐吗 - 工业品牌热点
  • java+vue基于springboot的旅游攻略分享系统的设计与实现_e7z2r88l
  • 中山净水器TDS值水质探头实力厂家哪家好 - 工业品牌热点
  • 2026年洗护套装价格大揭秘,靠谱生产厂和网店排名 - mypinpai
  • 2026年评价高的西安日式搬家,西安工厂搬家公司选型参考手册 - 品牌鉴赏师
  • java+vue基于springboot的医疗器械医疗设备管理系统设计与实现_7dq58k9j
  • 2026年可靠的殡葬一条龙,寿衣,殡葬流程公司实力推荐名录 - 品牌鉴赏师
  • 关于需要反弹功能的2d射击游戏向量计算
  • java+vue基于springboot的和Vue的毕业设计选题管理系统的设计与实现_cu9atc26
  • AI供应链安全:依赖库漏洞对预训练模型的污染检测工具深度解析
  • 2026年武汉好的推荐河湖治理工程公司,河北景达环保性价比高靠谱之选 - 工业设备
  • 联想Y700 2023状态栏实时网速开启攻略:拯救者用户必看,告别网络卡顿盲区
  • 软件架构设计:从理论到实践的深度指南
  • 为什么有时候能 ping 通却打不开网页?
  • 智慧校园顶层设计实施计划:分阶段推进,稳步落地
  • 你的论文,可能只是“太干净”了——百考通「降重+降AI」,给学术加点“人味儿”
  • 我终于能够在 Debian 13 上享受 KDE 6了,桌面稳定到让人尖叫
  • 少走弯路:9个降AI率平台深度测评,MBA必看!
  • 精益管理技巧:TPM 基础知识点拨,看完你就懂了