知识需要不断积累、总结和沉淀,思考和写作是成长的催化剂

异步多线程挺大一块内容,既想拆开慢慢学,又想一股脑全倒出。纠结再三,还是拆开吃透,也不至于篇幅过长,劝退许多人

本篇先做一个概述,列明一些基本概念

内容目录

一、进程和线程1、进程2、线程多线程后台线程3、简言之4、适用场景二、同步和异步1、同步2、异步3、异步编程4、Async、Await5、异步操作优缺点三、小结

一、进程和线程

1、进程

我们打开计算机的任务管理器,会发现系统的很多个进程,每个进程独占CPU、内存、磁盘、网络等资源,是资源分配的最小单元。多个进程之间是资源隔离的,数据之间不能直接传递。一个exe运行一次就会产生一个进程,运行多次就多个,但他们之间数据互相隔离

2、线程

同样在任务管理器中我们也能看到线程,一个进程是由多个线程组成的,且至少是由一个线程,那就是主线程。图中就可以看到线程的数量要比进程大的多

多线程

衡量一个人干活快,要么是一件事干的很快,要么是他能同时干很多事。计算机就是如此,以单核CPU类比单个人,理论上单位时间上只能运行一个进程里一个线程,只能干一件事。但线程有可能在某些操作比如读写磁盘时会等待,这时候磁盘在疯狂的运转,CPU却是闲置状态,直到磁盘读写完成才CPU才继续工作,所以空闲的这个时候它可以先去干别的事情,看起开就像单核它也可以同时干很多事

一个人可以把水壶烧上水的同时去拖地,同一时刻一个人是只能干一件事的,只是在快速的频繁切换,拖地时一直想着水开了没开了没,但如果处理不当,多线程效率还低,就像你没来及去倒已经烧开的水导致干锅,还有些任务同时起来更费时,就像你一边拖地一遍广播体操一样,伸展运动123然后拖一下地,然后接着,唉?到哪里了…

后台线程

后台线程不会阻止进程的关闭。当某个程序的所有前台线程完成后,进程就终止程序退出了,当然后台线程也会随即停止。在.NET中用Thread创建的线程默认都是前台线程,用线程池、BeginXXX等启用的线程都是后台线程

3、简言之

线程是独立执行单元,同一段代码(参数不同,任务不同)可以交给多个线程去执行,从宏观上看就是并行的执行,微观上时间片上还是串行执行的。但多核CPU就另说了,像多个人一样,一个人负责做饭,一个负责拖地

多线可以提高CPU的利用率,一个线程等待时,可以先去执行其他的任务,当然,线程之间的切换也是需要消耗资源的,开发复杂度也是会变大的,资源争夺也需要做合理的控制,也并不是所有的任务都适合多线程

4、适用场景

后台执行耗时任务,前台界面仍需要友好的展示。在WinForm中,如果单线程(也就是主线程)如果执行耗时的操作,那么界面就会失去响应,它忙于后台的任务,无法更新用户界面的交互。这个时候可以另开一个工作线程来处理耗时的任务,主线程可以响应用户操作,也可以随时改变任务的状态

在没有界面的程序里,当一个任务有潜在的耗时时,比如等待远程服务器的响应返回,用工作线程来完成任务可以让主线程去做其他事情

复杂的计算,多线程在多核CPU上可以更快的完成任务。总之一切都是为了效率,.NET中很多暗中的多线程,比如timer,backgroudworker,webservices等,我们使用中自然而然就在利用其多线程带来的好处,在了解了基本原理后,我们需要手动创建管理明面上的多线程任务

多线程纵然可以提高你的程序流畅度,但开发调试中确实增大了难度,一方面除了要对业务划分适应多线程的处理模式,另一个方面多线程最终还是交于操作系统的调度,我们虽可以执行一些优化调度,但最终结果并不是总尽人意,线程之间的切换也会消耗资源,所以多线程的设计应该尽量简单

二、同步和异步

1、同步

同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果,程序自上而下顺序执行,没完成一个指令,在进行下一个指令。在代码调试的表现为,光标一步一步完成上一步计算后,才会进入下一行。阻塞调用线程的运行

2、异步

异步方法则在被调用之后,调用线程不会等待方法的完成,会直接进入下一行,执行下一个指令,所以是非阻塞

3、异步编程

.NET通过委托可以实现异步调用任何方法。像上面介绍委托方法调用时,除了Invoke同步方法,还有BegInvoke异步方法,它会启用一个异步调用线程,你只需要传入委托方法的参数(可能还需要线程额外参数,如果有必要的话)就可以以后台线程的方式执行方法。在代码上执行到BeginInvoke时,会立即返回,不等待异步调用的完成,它返回一个IAsyncResult类型,你可以用它来监视调用的进度。和BegInvoke成对的EndInvoke方法可以用于获取异步调用的结果,这是会阻塞的。具体将在下一篇代码实例中讲解BeginInvoke的常用套路

4、Async、Await

Async、Await是.NET4.5新增的异步编程方式,为了简化异步程序的编写。上面的说的异步调用方式就是经典的APM异步编程模型,基于IAsyncResult接口实现BeginXXX和EndXXX类似的方法。在.NET4.5中可以使用Async方式,通过Async关键字标记方法为异步方法,然后在方法内部通过await标记后面的方法耗时,调用线程到这里就回去吧。我们就可以不用APM方式,用async方式可以轻松将一个方法编程异步方法

public async void Async1()
{
    HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("http://cnblogs.com/");
    await myReq.GetRequestStreamAsync();
    //to do

5、异步操作优缺点

异步操作相比较于多线程,减少了死锁的可能,在设计良好的情况下,异步函数可以不必使用共享变量,可以减少出错的几率。但起步也是难以调试的,只有尽量减少其复杂度

三、小结

这篇主要介绍一些概念,接下来硬核编码部分就不会再啰嗦这些,上面有遗漏的,在编码中会捎带一些。基本就这些吧,TaskFactory、ThreadPool、Task、Parallel等都是对Thread的封装,过一遍代码,了解常用方法套路就可以。不会面面俱到每个接口都试一下,微软官网文档更全面(吹一波,.NET微软大佬的技术支持还是杠杠的)。后面主要搞一些成熟的套路,比如线程的同步,线程取消,异常处理,线程安全、锁机制等可用的编码方式。

OK,那下期见,去给FPX打气去,拜了个拜~

可关注主页公号获取更多

兽人永不为奴

.NET进阶篇06-async异步、thread多线程1的更多相关文章

  1. 02: tornado进阶篇

    目录:Tornado其他篇 01: tornado基础篇 02: tornado进阶篇 03: 自定义异步非阻塞tornado框架 04: 打开tornado源码剖析处理过程 目录: 1.1 自定制t ...

  2. .NET进阶篇06-async异步、thread多线程4

    知识需要不断积累.总结和沉淀,思考和写作是成长的催化剂 梯子 一.锁1.lock2.Interlocked3.Monitor4.SpinLock5.Mutex6.Semaphore7.Events1. ...

  3. C#异步和多线程以及Thread、ThreadPool、Task区别和使用方法

    本文的目的是为了让大家了解什么是异步?什么是多线程?如何实现多线程?对于当前C#当中三种实现多线程的方法如何实现和使用?什么情景下选用哪一技术更好? 第一部分主要介绍在C#中异步(async/awai ...

  4. c# 异步( Async ) 不是多线程

    c# 异步( Async ) 不是多线程   误解 async 在调试 xxxxAsync() 方法的时候,常常会看到调试器界面中会多出一些线程,直觉上误认为 Async 冠名的函数是多线程. 对于 ...

  5. spring boot(17)-@Async异步

    验证码的异步机制 上一篇讲过可以用邮件发验证码,通常我们在某网站发验证码时,首先会提示验证码已发送,请检查邮箱或者短信,这就是图中的1和3.然而此时查看邮箱或短信可能并没有收到验证码,往往要过几秒种才 ...

  6. PowerBuilder编程新思维2:嵌入(Thread多线程)

    PowerBuilder编程新思维2:嵌入(Thread多线程) 在PB中使用多线程,在网上有大量的文章介绍.不过深入研究并试着给出更易用的模型的,目前还只有"路人甲cw"的一篇& ...

  7. Node.js进阶篇-koa、钩子函数、websocket、嵌入式开发

    代码地址如下:http://www.demodashi.com/demo/12932.html 一.简介     koa是由Express原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的We ...

  8. 在 .NET 4.0 下编写扩展代码以支持 async 异步编程

    微软在C# 5中引入了async.await这两个异步编程的关键字,要使用这两个关键字需要你的IDE支持C#5.0语法,也就意味着你需要使用VS 2012版本以上IDE,或者在Vs2010卸载其编译器 ...

  9. Oracle RMAN 学习:演练进阶篇

    Oracle RMAN 学习:演练进阶篇 5 Rman备份演练进阶篇 5.1 是否选择增量备份 Backup命令生成的备份集中只备份了那些使用了的数据块,备份集实际大小已经较目标数据库的数据文件小了很 ...

  10. Spring Boot (18) @Async异步

    通常我们在某网站发送邮件验证码时,首先会提示验证码已发送,然而此时可能没有收到验证码,过几秒种才真正的收到.如果是同步会先验证发送是否成功然后再通知,如果是异步可以先通知用户已发送,并释放请求,然后再 ...

随机推荐

  1. $(document).height 与$(window).height的区别

    $(document).scrollTop() 获取垂直滚动的距离 (即当前滚动的地方的窗口顶端到整个页面顶端的距离)$(document).scrollLeft() 这是获取水平滚动条的距离 要获取 ...

  2. 校园网 虚拟机VMware Linux桥接模式 无法上网 问题

    只是解决常见虚拟机桥接模式 无法上网问题,基本的百度都有 基本知识 虚拟机有三种网络连接模式:桥接模式,net模式,仅主机 桥接模式:同一网段允许的话,相当于一个独立的物理主机,独立ip net模式: ...

  3. js常用Matn函数的操练

    Math.PI console.log(Math.PI); 随机数以及向下取整 这是一个能实现从a-b之间随机打印一个整数 function rand_s(a, b) { var x = a + (b ...

  4. MongoDB 学习笔记之 WriteConcern

    WriteConcern: 转载:MongoDB WriteConcern(写关注)机制 http://www.ywnds.com/?p=3688&viewuser=40 MongoDB部署模 ...

  5. Windows内核编程时的习惯与注意事项

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 一.内核编程注意细节: 在头文件中使用的是 <ntddk.h ...

  6. Java8新特性之空指针异常的克星Optional类

    Java8新特性系列我们已经介绍了Stream.Lambda表达式.DateTime日期时间处理,最后以"NullPointerException" 的克星Optional类的讲解 ...

  7. 使用Jmeter并发websocket协议项目

    1.安装Jmeter 网址:http://jmeter.apache.org/下载 2.启动Jmeter \apache-jmeter-5.1.1\bin\jmeter.bat 3.安装‘Plugin ...

  8. JVM本地方法栈及native方法

    看到虚拟机栈和本地方法栈的区别的时候有点疑惑,因为本地方法栈为虚拟机的Native方法服务.以下转载一篇关于native方法的介绍: http://blog.csdn.net/wike163/arti ...

  9. Numpy中的一点小知识

    train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()train_set_x_orig ...

  10. Flask的路由解读以及其配置

    from flask import Flask app =Flask(__name__) 一.配置 配置一共有四中方式 方法一: 只能设置以下两种属性 app.debug=True app.secre ...