很久没安下心来写博客了,几年的开发过程中,对于异步与并行的了解也随着清淅起来。首先很多人问我,异步与并行的区别,那么我们来了解下概念。

本博文写的主旨是用最白话的语言来说明问题,不想照搬概念。

在古老的单核计算机中,一般是单核的,并行也只是在进程中交替的执行,表现出来的像并行执行一样,只是时间比较短,在多核处理器的计算机中,进程不仅可以交替执行,而且可以重叠执行,所以说,并行,只有在多核处理器中才有真正意义。很多人可能会突然不理解,并行与并发,是什么区别,并行,就像两种时刻相同的进程同一时刻运行,而并发不一定同一时刻运行,这就微妙的区别。

就拿订单来说吧,在下单超大的情况下,A用户下了一个订单,还没有来及结束,B用户又下了一个订单。那么,这时最有可能发行的情况就是并发事件。

那么我们今天重点说说异步,异步,是相对于同步来说的,我们知道,应用程序都是由一个主线程来运行的,这个主线程,是按照顺序来处理我们写的逻缉代码的,这就是同步,引用异步的好处是,在不打挠主线程的前提下,继续开放一个线程来指行其它的事情,就相当于,把部分工作交接给别人,当别人做好了后,然后,对我说,你交待的任务我已做好了。别人做好的工作交待给我的过程,相当于结果的返回中断。

异步最终的目的就是给我们带来更高效的时间效应,它是一种结果,而实现这个异步的可能是异步委托,线程池,线程等等,只不过是一种方法或途径罢了,这就是线程与异步的最好诠释。

下面来说说异步自然缺少不了多线程这个重头戏。

实现多线程方式很多,下面一个一个的讲起。

1.投票

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1
{class Program{public delegate decimal TakeDelegate(decimal data, int ms);  static void Main(string[] args)  {DateTime now = DateTime.Now;TakeDelegate dl = SaveBankAccount;IAsyncResult ar=  dl.BeginInvoke(1, 200, null, null);while(!ar.IsCompleted){Console.WriteLine("main thread wating current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Thread.Sleep(50);}decimal result = dl.EndInvoke(ar);Console.WriteLine("CurrentMoney:{0}", result);Console.WriteLine("runtime:{0}", (DateTime.Now-now).TotalSeconds);Console.WriteLine("main thread IsBackground " + Thread.CurrentThread.IsBackground);Console.ReadKey();}static decimal SaveBankAccount(decimal money,int ms){Console.WriteLine("SaveBankAccount thread started! current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Console.WriteLine("SaveBankAccount thread IsBackground " + Thread.CurrentThread.IsBackground);Thread.Sleep(ms);Console.WriteLine("SaveBankAccount thread completed!");return ++money;}}
}

一直都在想一个问题,为什么这种方式名字叫投票!百度 google都没有结果,最后想着想着也就想清楚了,所谓投票,就是对结果的一种猜测,“是否结束投票”


2.异步回调

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1
{class Program{public delegate decimal TakeDelegate(decimal money,int ms);static DateTime now = DateTime.Now;static void Main(string[] args)  {TakeDelegate dl = SaveBankAccount;var ar = dl.BeginInvoke(1, 200, AsyncCallBack,dl);while(!ar.IsCompleted){Console.WriteLine("main thread wating current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Thread.Sleep(50);}Console.ReadKey();}static decimal SaveBankAccount(decimal money,int ms){Console.WriteLine("SaveBankAccount thread started! current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Console.WriteLine("SaveBankAccount thread IsBackground " + Thread.CurrentThread.IsBackground);Thread.Sleep(ms);Console.WriteLine("SaveBankAccount thread completed!");return ++money;}static void AsyncCallBack(IAsyncResult ar){if (ar == null){throw new ArgumentNullException("ar");}TakeDelegate dl = ar.AsyncState as TakeDelegate;decimal result = dl.EndInvoke(ar);Console.WriteLine("CurrentMoney:{0}", result);Console.WriteLine("runtime:{0}", (DateTime.Now - now).TotalSeconds);Console.WriteLine("main thread IsBackground " + Thread.CurrentThread.IsBackground);}}
}

这个方法是在投票的基础,加入了回调函数而已。还有一种方法于投票差不多,就是等待句柄(AsyncWaitHandle),这个方法与投票没有太大的差异。没事的同学可以百度一下,这里就不多说了。

如果说到这里,那么,我想微软也太失败了,因为这样玩异步太操心,那么多的代码。

随着时间的推移,微软在.net3.0 C# 3.0的大包裹越来越健全 拉姆达(lambda)表达式与匿名方法 孕育而生。

好吧,我们对上面的代码是时候要简化的必要了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1
{class Program{static void Main(string[] args){DateTime now = DateTime.Now;Func<decimal, int, decimal> f = SaveBankAccount;var ar = f.BeginInvoke(1, 200, (r) =>{if (r == null){throw new ArgumentNullException("r");}Console.WriteLine("CurrentMoney:{0}", f.EndInvoke(r));Console.WriteLine("runtime:{0}", (DateTime.Now - now).TotalSeconds);Console.WriteLine("main thread IsBackground " + Thread.CurrentThread.IsBackground);}, null);while (!ar.IsCompleted){Console.WriteLine("main thread wating current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Thread.Sleep(50);}Console.ReadKey();}static decimal SaveBankAccount(decimal money, int ms){Console.WriteLine("SaveBankAccount thread started! current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Console.WriteLine("SaveBankAccount thread IsBackground " + Thread.CurrentThread.IsBackground);Thread.Sleep(ms);Console.WriteLine("SaveBankAccount thread completed!");return ++money;}}
}

再次狠狠的优化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace ConsoleApplication1
{class Program{static void Main(string[] args){DateTime now = DateTime.Now;Func<decimal, int, decimal> f = (money, ms) =>{Console.WriteLine("SaveBankAccount thread started! current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Console.WriteLine("SaveBankAccount thread IsBackground " + Thread.CurrentThread.IsBackground);Thread.Sleep(ms);Console.WriteLine("SaveBankAccount thread completed!");return ++money;};var ar = f.BeginInvoke(1, 200, (r) =>{if (r == null){throw new ArgumentNullException("r");}Console.WriteLine("CurrentMoney:{0}", f.EndInvoke(r));Console.WriteLine("runtime:{0}", (DateTime.Now - now).TotalSeconds);Console.WriteLine("main thread IsBackground " + Thread.CurrentThread.IsBackground);}, null);while (!ar.IsCompleted){Console.WriteLine("main thread wating current run at treadID:" + Thread.CurrentThread.ManagedThreadId);Thread.Sleep(50);}Console.ReadKey();}}
}

着重看下两个划框的部分,lambda表达式采用匿名方法成功的简化了传统的方式,里面的参数获取,将来的更为便捷,所以四个参数后,用了null。

public delegate TResult Func<in T, out TResult>(T arg) 委托 是微软在.net 3.5 再次对delegate的封装,第一个参数是输入参数,第二个是返回参数,此时,我们不用太辛苦的到处声明委托,这点微软也给我们省了,不得不说,代码的优美不是java能比的。

细心的朋友可能看到上面一段代码 IsBackground 这个时候,表示线程是前台线程还是后台线程。

前台线程与后台线程的区别:

就像word文档一样,打开word 即开启了word主线程即前台线程,诸如 语法检查属于后台线程,仔细想想,这样设计,还是有道理的,当关闭了word前台主线程,后台线程语法检查也没有必要了。

一个进程里必须有一个前台线程,不一定有后台线程。当前台线程已结束的时候,后台线程也将结束。

看下面代码

通常,应该将被动侦听活动的线程设置为后台线程,而将负责发送数据的线程设置为前台线程,这样,在所有的数据发送完毕之前该线程不会被终止。只有在确认线程被系统随意终止没有不利影响时,才应该使用后台线程。如果线程正在执行必须完成的敏感操作或事务操作,或者需要控制关闭线程的方式以便释放重要资源,则使用前台线程。

例如 《C#高级编程》中有个例子--如果关闭Word程序,拼写检查器还在运行其进程就没有意义了。在关闭应用程序时拼写检查器线程就可以关闭。

小结:本节只是对于基础知识线程与异步委托作了个简单的复习,让我联想到,主线程也好,新开的线程也好,无非都是线程的部分,线程更多的是一种方法,而异步是一个需要线程支撑的结果,所以可以在任何线程上开启异步的操作,因为主线程都可以开启异步嘛。

未完待续...

转载于:https://www.cnblogs.com/laogu2/p/5885880.html

大话异步与并行(一)相关推荐

  1. F#中的异步和并行设计模式(三):代理

    在这个系列的第三部分,我们解释了F#中的轻量级代理的和交互式代理,并且看过了一些与之相关的典型的设计模式,包括内部隔离状态. 第一部分分描述了F#是一种并行交互式语言及如何支持轻量级交互操作的,并且为 ...

  2. promise异步请求串行异步then并行异步all竞争异步race 传递参数resolve(then)reject(catch)

    1.印象 古人云:"君子一诺千金",这种"承诺将来会执行"的对象在JavaScript中称为Promise对象. Promise就是解决多个异步请求的问题 Pr ...

  3. .net core精彩实例分享 -- 异步和并行

    文章目录 介绍 具体案例 等待线程信号--ManualResetEvent 等待线程信号--AutoResetEvent 多个线程同时写一个文件 串联并行任务 使用Parallel类执行并行操作 为每 ...

  4. 【JavaScript】同步与异步-异步与并行-异步运行机制-为什么要异步编程-异步与回调-回调地狱-JavaScript中的异步操作

    文章目录 1. 同步与异步 1.1 同步行为synchronous 1.1.1 特点 1.1.2 例子 1.2 异步行为asynchronous 1.2.1 必要性 1.2.2 特点 1.2.3 例子 ...

  5. 同步与异步、并行与并发、阻塞与挂起

    同步与异步.并发与并行.阻塞与挂起 同步与异步 并行与并发 阻塞与挂起 同步与异步   同步(synchronous)是指多个有相互之间一定联系的并发执行的进程,通过一定的机制,使之有序执行,从而使其 ...

  6. CreateFile系类异步、并行(同一个串口发送接收)

    在Windows系统下,串口数据收发CreateFile系类方法对于我来说是最好用的方法,采用异步机制保证了串口读或写入不会使代码停在串口函数内(停在串口函数内原因可能是串口线的原因,或者串口没打开( ...

  7. 同步,异步,并行概念的歪解

    以前在网上搜索同步.异步的概念的时候,有网友把它们进行了歪解,感觉比较有趣,摘录如下 : 有一个男的 看上了两个漂亮MM 想通过写信的方式跟他们交流感情 这两个MM分别是 A女,B女 同步:他先给A女 ...

  8. 异步与并行~ReaderWriterLockSlim实现的共享锁和互斥锁

    返回目录 在System.Threading.Tasks命名空间下,使用ReaderWriterLockSlim对象来实现多线程并发时的锁管理,它比lock来说,性能更好,也并合理,我们都知道lock ...

  9. Cuda异步计算并行编程设计和优化

    基于Cuda开发GPUGPU程序时,最重要的仍然是内核的设计,这是Cuda性能优化的难点,提供了不少岗位,养活了一大批工程师.这里以一个相对简单的的求平方和算法为例,从编程和优化,调试几个维度,介绍利 ...

最新文章

  1. 线程中CreateEvent和SetEvent及WaitForSingleObject的用法
  2. 《java基础知识》Java变量作用域
  3. SAP ABAP实用技巧介绍系列之 ABAP XSLT apply_template keyword
  4. mysql中int、bigint、smallint 和 tinyint的区别与长度
  5. IEEE期刊论文模板的查找,下载方法--
  6. Linux面试题(总结最全面的面试题!!!)
  7. 2019年全国大学生电子设计竞赛G题解决方案-双路语音同传的无线收发系统
  8. 我说CMM2.0之:风险与机会管理
  9. 整数规划--指派问题
  10. C语言华氏度转换摄氏度
  11. JAVA集成微信支付 周期扣费
  12. AI缘起 —— 达特茅斯会议
  13. php mp4 ckplayer,ckplayer:超酷网页视频播放器
  14. mysql ix is_关于MySQL中的共享锁(S)、排它锁(X)、意向共享锁(IS)、意向排它锁(IX)...
  15. html网页制作提交注册信息,利用HTML表单标签编写一个注册页面
  16. 清华大学计算机研究生课程表
  17. 人工神经网络的训练步骤,神经网络常用训练方法
  18. 第4节 操作器和Trackball
  19. 【笔记】GEE之python学习
  20. Angular14 Visual Studio Code作为Angular开发工具常用插件安装、json-server安装与使用、angular/cli安装失败问题、emmet安装...

热门文章

  1. SpringMVC-方法四种类型返回值总结,你用过几种?
  2. flink-faker用法示例(还没弄完,到时候再说)
  3. spark中各类key算子的用法汇总(持续更新中)
  4. Django的电子商务网站的调研
  5. git commit时避免填写Commit Message
  6. 张量的通俗理解和计算
  7. SVM和感知机的区别(转载+自己笔记)
  8. stanford python中文分词
  9. ubuntu16.04下面流畅运行pycharm设置
  10. Ubuntu 16.04下面安装grub-customizer来切换ubuntu+win7双系统开机启动顺序