改善C#程序的157个建议(连载71)

发表于:2011-11-08 09:51

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陆敏技    来源:51Testing软件测试网采编

#
DotNet
分享:

  第6章 异步、多线程、任务和并行

  在软件开发过程中,有一个领域的工作处理起来几乎总是最棘手的,这就是多线程编码。由多线程带来的传值、取值、资源同步、线程暂停、取消等操作会困扰每一个尝试编写此类代码的程序员。微软在这方面也做了巨大的努力,现在FCL中有了非常丰富的API可供选择,以便编写多线程代码。但这也带来了一个新问题:选择太多了,该选择什么样的类和方法呢?

  本章将通过具体的实例,让我们熟悉异步、多线程、任务和并行。我们会了解到异步的实质、任务的实质,以及为什么有了任务还需要一个并行类(Parallel)等问题。同时,本章内容还会告诉我们如何优雅地控制线程,并且处理任务和并行中的异常。

  多线程编码是所有开发人员前进途中的一个坎,现在,该是尝试克服它的时候了。

  建议71:区分异步和多线程应用场景

  初学者有时候会将异步和多线程混为一谈。如果对它们之间的区别不是很清楚,很容易写出下面这样的代码:

  1. private void buttonGetPage_Click(object sender, EventArgs e)  
  2. {  
  3.     Thread t = new Thread(() => 
  4.     {  
  5.         var request = HttpWebRequest.Create("http://www.cnblogs.com/luminji");  
  6.         var response = request.GetResponse();  
  7.         var stream = response.GetResponseStream();  
  8.         using (StreamReader reader = new StreamReader(stream))  
  9.         {  
  10.             var content = reader.ReadLine();  
  11.             textBoxPage.Text = content;  
  12.         }  
  13.     });  
  14.     t.Start();  
  15. }

  上面的代码模拟了在一个Winform窗体程序中,单击Button获取某个网页的内容并显示出来。可以预见,如果该网页的内容很多,或者当前的网络状况不太好,获取网页的过程会持续较长时间。于是,我们可能会想到用新起工作线程的方法来完成这项工作,这样在等待网页内容返回的过程中Winform界面就不会被阻滞了。

  是的,上面的程序解决了界面阻滞的问题,但是,它高效吗?答案是:不。要理解这一点,需要从“IO操作的DMA(Direct Memory Access)模式”开始讲起。DMA即直接内存访问,是一种不经过CPU而直接进行内存数据存储的数据交换模式。通过DMA的数据交换几乎可以不损耗CPU的资源。在硬件中,硬盘、网卡、声卡、显卡等都有DMA功能。CLR所提供的异步编程模型就是让我们充分利用硬件的DMA功能来释放CPU的压力。

  了解这一点,再来重新审视本建议开头的这个例子。其开头部分的示例代码可以用图6-1来阐述。

图6-1 多线程工作的示意图

  为了获取网页,CLR新起了一个工作线程,然后在读取网页的整个过程中,该工作线程始终被阻滞,直到获取网页完毕为止。在整个过程中,工作线程被占用着,这意味着系统的资源始终被消耗着、等待着。

21/212>
100家互联网大公司java笔试题汇总,填问卷领取~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号