建议71:区分异步和多线程应用场景
建议71:区分异步和多线程应用场景
初学者有时候会将异步和多线程混为一谈。如果对它们之间的区别不是很清楚,很容易写出下面这样的代码:
private void buttonGetPage_Click(object sender, EventArgs e) { Thread t = new Thread(() =>{ var request = HttpWebRequest.Create("http://www.cnblogs.com"); var response = request.GetResponse(); var stream = response.GetResponseStream(); using (StreamReader reader = new StreamReader(stream)) { var content = reader.ReadLine(); textBoxPage.Text = content; } }); t.Start(); }
上面的代码模拟了在一个Winform窗体程序中,单击Button获取某个网页的内容并显示出来。可以预见,如果该网页的内容很多,或者当前的网络状况不太好,获取网页的过程会持续较长时间。于是,我们可能会想到用新起工作线程的方法来完成这项工作,这样在等待网页内容返回的过程中Winform界面就不会被阻滞了。
是的,上面的程序解决了界面阻滞的问题,但是,它高效吗?答案是:不。要理解这一点,需要从“IO操作的DMA(Direct Memory Access)模式”开始讲起。DMA即直接内存访问,是一种不经过CPU而直接进行内存数据存储的数据交换模式。通过DMA的数据交换几乎可以不损耗CPU的资源。在硬件中,硬盘、网卡、声卡、显卡等都有DMA功能。CLR所提供的异步编程模型就是让我们充分利用硬件的DMA功能来释放CPU的压力。
了解这一点,再来重新审视本建议开头的这个例子。其开头部分的示例代码可以用图6-1来阐述。
图6-1 多线程工作的示意图
为了获取网页,CLR新起了一个工作线程,然后在读取网页的整个过程中,该工作线程始终被阻滞,直到获取网页完毕为止。在整个过程中,工作线程被占用着,这意味着系统的资源始终被消耗着、等待着。
如果我们修改一下代码,使用异步模式去实现,代码如下所示:
private void buttonGetPage_Click(object sender, EventArgs e) { var request = HttpWebRequest.Create("http://www.cnblogs.com"); request.BeginGetResponse(this.AsyncCallbackImpl, request); } public void AsyncCallbackImpl(IAsyncResult ar) { WebRequest request = ar.AsyncState as WebRequest; var response = request.EndGetResponse(ar); var stream = response.GetResponseStream(); using (StreamReader reader = new StreamReader(stream)) { var content = reader.ReadLine(); textBoxPage.Text = content; } }
以上代码的工作机制可以用图6-2来描述。
图6-2 异步工作的机制
经过修改的示例采用了异步模式,它使用线程池进行管理。新起异步操作后,CLR会将工作丢给线程池中的某个工作线程来完成。当开始I/O操作的时候,异步会将工作线程还给线程池,这时候就相当于获取网页的这个工作不会再占用任何CPU资源了。直到异步完成,即获取网页完毕,异步才会通过回调的方式通知线程池,让CLR响应异步完毕。可见,异步模式借助于线程池,极大地节约了CPU的资源。
明白了异步和多线程的区别后,我们来确定两者的应用场景:
- 计算密集型工作,采用多线程。
- IO密集型工作,采用异步机制。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
建议71:区分异步和多线程应用场景相关推荐
- 同步,异步,多线程,你怎么看?
同步,异步,多线程,你怎么看? 原文:同步,异步,多线程,你怎么看?[原创] 讲解同步与异步的帖子多如牛毛,个人的理解,简单地说同步就是串行,异步就是并行.同步的情况下,A调用B,A等B执行完成后接着 ...
- Linux异步管道多线程速率测试-原始数据
<Linux异步管道多线程速率测试>https://rtoax.blog.csdn.net/article/details/107812606 包大小 单线程 双线程 三线程 四线程 五线 ...
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Application.LoadLevel("yourSc ...
- .NET异步和多线程系列(四)- 多线程异常处理、线程取消、多线程的临时变量问题、线程安全和锁lock
本文是.NET异步和多线程系列第四章,主要介绍的是多线程异常处理.线程取消.多线程的临时变量问题.线程安全和锁lock等. 一.多线程异常处理 多线程里面抛出的异常,会终结当前线程,但是不会影响别的线 ...
- java中同步和异步简介及应用场景
转自: java中同步和异步简介及应用场景 同步: 同步指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系. 本意是指某人或某事同时进行:同时产生,比如音画同步.动作同步等. 同步,指对在一 ...
- 【Java线程】互斥 同步 异步 并发 多线程的区别与联系
1. 并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行.其中两种并发关系分别是同步和互斥: 2. 互斥:进程间相互排斥的使用临界资源的 ...
- 同步异步单线程多线程初级理解
对于我开始接触同步异步单线程多线程的概念的时候,都是分别理解同步和异步.单线程和多线程概念,当看到"使用同步方法保证线程安全"时愚昧的理解为那就是单线程咯:于是就陷入了困惑,同步等 ...
- 异步、多线程、任务、并行编程之一:选择合适的多线程模型
本篇概述: @FCL4.0中已经存在的线程模型,以及它们之间异同点: @多线程编程模型的选择. 1:异步.多线程.任务.并行的本质 这四个概念对应在CLR中的本质,本质都是多线程. 异步,简单的讲就是 ...
- Linux异步管道多线程速率测试
目录 结论 源代码 main.c utils.h utils.c Makefile test.sh 文章链接 结论 总体上说,由于是异步,多线程发包对单线程的处理不收很大影响,但是包的大小对发包速率影 ...
最新文章
- python3上传文件_Python3学习笔记(十八):文件上传和下载
- Postman Could not get any response
- 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1081:分苹果
- 如何获取网站icon
- Can‘t bind to formControl since it isn‘t a known property of input错误消息的处理
- CSS Grid布局(1)
- 白话数字签名(1)——基本原理
- 【元胞自动机】基于matlab保守策略元胞自动机三车道(开放辅路,软件园影响)交通流模型【含Matlab源码 1295期】
- 测试项目实战----RuoYi后台管理系统
- usb调试软件_想防止软件后台偷偷运行,那就把它们冻结起来
- reimage许可证密钥_思科 ASA 和 Firepower 威胁防御重新映像指南
- win7计算机自动关机设置在哪里设置方法,win7电脑自动关机怎么设置_win7电脑自动关机怎么设置在哪-win7之家...
- 较为安全快捷的更改C盘用户文件夹名称的方式!(2022.8.22)windows10和11均可用
- 什么是robots协议,robots文件的作用有哪些!
- 微擎api.php,微擎支付api发起支付并验证
- 「击败星际争霸II职业玩家」的 AlphaStar是在作弊?
- ffmpeg在低版本VS中的编译
- 计算机和电脑键盘进水怎么办,笔记本键盘进水失灵了怎么办?别着急,只需记住这几招!...
- 自媒体娱乐热点素材怎么找?-即时热榜
- MMA8451Q传感器读值