线程异步收集整理(转载整理)

(一)线程
(道法自然)
该技术说的有点抽象,没有用浅显易懂语言表述,其实在WinForm时代,每一个Form就有Invoke和BeginInvoke的。在这里,我补充一点:
(1)什么是呈现线程和UI线程:在我理解中,呈现线程仅是用于绘画窗口界面元素,每一个绘画都是由UI线程触发的,UI线程向消息队列发送绘画相关消息,由呈现线程实现绘画

,比如重绘消息。
(2)在可视化应用中,如果,没有新建线程,那么所有代码都是由UI线程执行的,因此,在执行一个大任务时,由于UI线程忙,无法发送重绘消息,窗口就不会有响应,好像死掉

一样。
(3)对UI的操作,比如更改控件属性(引起重绘),都必须由UI线程来执行,其它线程来更改UI的信息的话,会抛出异常。
(4)为了避免执行大任务导致窗口没有反应,你需要新建一个线程,让它执行任务,当新线程需要操作UI时,它需要利用Invoke和BeginInvoke来操作,这两个函数最终转给UI线

程执行。
WPF线程
(1)WPF 应用程序从两个线程开始:一个用于处理呈现,一个用于管理 UI。呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入、处理事件、绘制屏幕以及运行应用程序代

码。
(2)UI 线程对一个名为 Dispatcher 的对象内的工作项进行排队。 Dispatcher 基于优先级选择工作项,并运行每一个工作项,直到完成。每个 UI 线程都必须至少有一个

Dispatcher,并且每个 Dispatcher 都只能在一个线程中执行工作项。


要创建快速响应的桌面软件,我们就得将一些耗时操作,比如访问远程数据库,访问大文件等放到与UI主线程不同的线程里去做,免得阻塞主线程,造成UI挂起的现象,用户以为

程序挂了。如是我们就以为Thread是一剂良方,可以充分利用CPU的资源
耗时的操作阻塞了UI线程,造成UI线程不能响应用户操作。

(二)异步
在发起耗时操作的请求之后要立即返回,不要阻塞UI线程,让UI线程可以继续响应用用户的操作。然后等耗时操作返回后,通过回调来处理耗时操作返回的结果

(三)适用于异步的应用主要分为两种类型:
响应灵敏的界面和可伸缩性良好的服务应用。
(四)我的应用是计算密集型的还是IO密集型的
(1)计算密集型,CPU是主要资源。那什么类型的应用是计算密集型的,比如解方程,排序,压缩,图形图像处理等。对于这类应用无论怎样你都必须占用CPU时间,所以你可以通过

创建后台线程的方式来实现异步。(创建更少的线程干更多的活儿)
(2)IO密集型,IO是主要瓶颈。IO不仅仅是我们常说的读取磁盘文件,像数据库操作、FTP、HTTP等一切网络通信,磁盘访问等都属于IO。当我们进行IO操作时,我们实际上是不需

要占用CPU的,比如磁盘访问,一般现代的磁盘驱动器都有自己的控制系统,它自己能够控制寻道等,就相当于磁盘自己有一个小CPU在工作,而我们机器的CPU这个时候就可以解放

出来(不用等待,可以干其他的活儿),是不占用的。那么这个时候如果我们能使用异步IO(发起异步IO然后立即返回,当异步IO执行完毕后会通知你)将会对我们的应用的效率

带来革命性的影响,因为IO相对于CPU来说是非常非常非常慢速的设备,我们甚至只需要很少的线程就可以处理很多的任务。

(五)异步的实现
(1)线程
(2)BeginInvoke & EndInvoke
     NET里委托还提供了另外两个方法:BeginInvoke和EndInvoke用来实现异步。其实这种实现方式跟使用线程来实现是类似的,都会占用CPU时间,如果遇到IO操作,该线程还是

会一样阻塞。
这个时候你又在思考,不让我使用线程,又要让我实现异步。这该怎么办呢?微软早就帮你想到了这点,在.NET Framework中,几乎所有进行IO操作的方法几乎都提供了同步版本

和异步版本,而且微软为了简化异步的使用难度还定义了两种异步编程模式:
 (3)Classic Async Pattern(CAP)经典异步模型
这种方式就是提供两个方法实现异步编程:比如System.IO.Stream的Read方法:
public int Read(byte[] buffer,int offset,int count);
它还提供了两个方法实现异步读取:
public IAsyncResult BeginRead(byte[] buffer, int offset,int count,AsyncCallback callback);
public int EndRead(IAsyncResult asyncResult);
以Begin开头的方法发起异步操作,Begin开头的方法里还会接收一个AsyncCallback类型的回调,该方法会在异步操作完成后执行。然后我们可以通过调用EndRead获得异步操作的

结果
(4)Event-based Async Pattern(EAP)基于事件的异步模型
比如WebClient的很多方法就提供了异步版本,比如DownloadString方法。
同步版本:
public string DownloadString(string url);
异步版本:
public void DownloadStringAsync(string url);
public event DownloadStringCompleteEventHandler DownloadStringComplete;

(六)异步编程的尴尬
(1)异步,则意味着一个任务至少要被拆分为“二段式”的调用方式:一个方法用于发起异步请求,另一个方法用于异步任务完成后的回调
 (2)与传统方法的调用方 式相比,异步调用时的中间数据不能存放在线程栈上,方法之间的也不能简单地通过参数传递的方式来共享数据。此外,传统方法调用中可使用的 try…

catch…finally,using等关键字都无法跨越方法边界,因此异步编程在处理异常,保护资源等方面也需要花更大的精力才行。如果一不 小心,轻则造成资源泄露,重则使整个应

用程序崩溃。
(3)虽然微软费尽心思,提出两种异步编程的模式,让我们编写异步代码能稍微轻松那么一点点;但不管是使用回调还是基于事件的异步模式,都会将顺序的同步方式的代码拆成

两个部分:一个部分发起异步操作,而另外一个部分获得结果。当有多个异步操作要进行时(比如上面的代码首先使用异步的方式获得response,然后又使用异步的方式读取

stream中的内容)就会回调里嵌套着另外一个异步调用,代码更加混乱。而且方法打散之后,像using、for、while、常规的异常处理都变得难以进行。代码的可读性也急剧降低,

代码又容易出错,如是我们舍尔求其次,转而去使用低效的同步版本。

(七)辅助类库让异步更简单
Jeffrey Richter的AsyncEnumerator,以及微软的CCR


 
参考
http://www.cnblogs.com/Zhouyongh/archive/2009/08/31/1557126.html
http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx
http://msdn.microsoft.com/zh-cn/library/ms741870.aspx
http://www.cnblogs.com/zhouyongh/archive/2009/08/31/1557126.html
http://www.cnblogs.com/zhouyongh/archive/2011/01/12/1933414.html
http://www.cnblogs.com/yuyijq/archive/2011/02/20/1958925.html
http://www.cnblogs.com/yuyijq/archive/2011/02/22/1960273.html
http://www.infoq.com/cn/articles/ccr-async-parti
http://www.infoq.com/cn/articles/ccr-async-partii
http://www.cnblogs.com/net66/archive/2005/08/03/206132.html
http://www.cnblogs.com/ilove/archive/2008/04/06/1139316.html
http://www.cnblogs.com/ILove/archive/2008/04/06/1139446.html
http://www.cnblogs.com/scy251147/archive/2012/03/03/2378477.html

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/Joetao/articles/2398621.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值