C#中多线程机制带来异常的解决方法

来源 :硅谷 | 被引量 : 0次 | 上传用户:mmyxj
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要: 用C#进行Windows窗体编程时,如果用到跨线程调用控件时,经常遇到抛出一些异常。而多线程技术在开发一些大中型项目中是经常用的。针对这些异常提出一种用委托方法的解决机制。
  关键词: 多线程;C#;异常;委托
  中图分类号:TB文献标识码:A文章编号:1671-7597(2011)0320034-01
  
  在构建一些大中型系统时多线程技术往往受到青睐,合理应用能极大提高系统效率。它把一些需要执行较长时间的任务做为进程的一些线程,使它们同时执行,无须用户干预。然而,一旦多线程被使用,在Windows窗体编程中程序往往抛出一些Invalidate Operation的异常。这是因为使用线程操作常常会是复杂而且危险的,因此微软在.NETFramework2.0及以后版本都对线程的操作进行了限制。
  1 多线程的概念
  在Windows 32平台上,应用程序的宿主是进程,进程是应用程序所占的内存及外部资源的总和。每一个运行的进程都至少有一个主线程,主线程是第一个启动的线程,是从main函数开始的。在主线程之外可以生成若干个其它线程,称为工作者线程,用以在“同一时刻”完成多项任务,如字处理软件可以同时进行打印和编辑操作。像这种在主线程之外引入若干个工作者线程的操作成为多线程机制。
  2 多线程的产生
  多线程机制下,一个进程由一个主线程和若干个工作者线程组成。应用程序运行时会首先启动主线程即从Main函数开始执行。在主线程执行过程中,其内部代码可根据需要产生多个工作者线程。
  工作者线程产生有两种途径:1)通过System. Threading命名空间的Thread类产生,方法格式为Thread threadName=new Thread(new Thread
  Start(methodName));threadName为工作者线程名称,methodName为需要执行的方法名称。通过这个语句,我们可以方便地将某个方法作为一个单独的线程处理。2)系统自动分配产生,有些特殊方法或语句在执行过程中会自动产生一个工作者线程。如在通过回调函数取得异步方法执行的结果时,回调方法通常在与主线程不同的线程中执行。
  3 异常的产生
  .NETFramework2.0前的时代可以通过工作者线程在主线程创建控件,这样操作实质是很危险的,如果有两个或多个线程同时操作某一控件的某状态,则极有可能使该控件的某受控制的状态进入一种无所适从的境地。微软在.NETFramework2.0及以后版本都对线程的操作进行了限制。因此,从不是创建控件的线程访问或操作另一线程中创建的控件,经常引起Invalidate Operation和ArgumentExcepion等异常。下面是一个产生异常的例子,建立一个窗体应用程序项目,命名为MultiThread,主要代码如下。
  public partial class Form1 : Form
  {
  public Form1()
  {
  InitializeComponent();
  Thread newThread = new Thread(new ThreadStart(setText));//产生一个工作者线程
  newThread.Start();
  }
  private void setText()
  {
  textBox1.Text =“newText”;
  }
   }
  4 异常的解决方法
  C#默认不允许一个线程中直接访问或操作另一线程中创建的控件,textBox1在主线程中操作的,因此在newThread线程中操作textBox1是不安全的,抛出异常。应用托管可以很好的解决这一问题。
  VS开发环境中,Windows窗体控件的每个控件都有InvokeRequired属性,该属性就是用来检查本控件是否被其他线程调用,当被创建该控件的线程外的其它工作者线程调用的时候InvokeRequired就为true。有了这个属性我们就可以利用它来做判断了。当该属性为true时,我们可以用Windows窗体控件中的Invoke方法结合委托就,可以帮我们完成其他线程对控件的访问和操作。修改后的代码如下,此时没有抛出异常。
  delegate void setTextDelegate();//定义委托
  public partial class Form1 : Form
  {
  public Form1()
  {
  InitializeComponent();
  Thread newThread = new Thread(new ThreadStart
  (setText));//产生一个工作者线程
  newThread.Start();
  }
  private void setText()
  {
  if (textBox1.InvokeRequired)
  {
   setTextDelegate set = new setTextDelegate
  (setText);//委托的一个实例
  textBox1.Invoke(set);
  }
  else
  textBox1 .Text=“newText”;
  }
  }
  5 结论
  多线程操作可能会对同一个资源进行访问或操作,如果不采取适当的方法,很容易产生异常,使得程序无法运行。本文提出一种用委托方法的解决机制,当然还可以利用线程同步的方法。
  
  
  参考文献:
  [1]孙继磊、刘亮亮,精通VisualC#2008语言基础、数据库系[M].北京:人民邮电出版社,2009.
  [2]许毅、冯山,使用C#语言进行多线程程序设计[J].计算机工程,2003,29(5):172-l73.
  [3]张青、郭亚萍,C#编程思想与实践[M].北京:冶金工业出版社,2006.
  作者简介:
  李成浩(1983-),男,江西冶金职业技术学院机电工程系教师。
   注:“本文中所涉及到的图表、公式、注解等请以PDF格式阅读”
其他文献
作为一名学生,每个人都会有自己的学习方法,只要能够找出一种适合自己的学习方法就足以令我们笑对高考了.学习方法不是与生俱有的,它是在学习的过程中慢慢摸索、发掘出来的,
高中的学习就像一次曲折漫长的旅程,而高考便是这次旅程的终点.如今大家正在加足马力,开始冲刺.作为一个过来人,我把自己的一些心得给大家说说,希望能给你们带来帮助.
圣诞节和元旦节前夕,校园里同学们都大量地买贺卡,互相赠送,还有的送给老师、亲友,有一位同学从批发市场买回80多张贺卡.为了回报友谊,我也准备买些贺卡.我发现今年的贺卡大
教育的对象是学生 ,教师对学生真诚的爱 ,是教师赢得学生的信赖与爱戴的重要前提。“感人心者莫先乎于情” ,情感是思想教育的催化剂 ,是打开学生心扉的“金钥匙” ,只有当教
我国是一个水资源空间分布不均,时间变化很大的国家.所以,我国先后修建了大中小水库8万多座,总库容达1700亿立方米.水库的作用是在河流洪水期蓄水,枯水期放水.修建这么多水库
摘要: 能源短缺是人类当前共同面临的世纪性难题。我国人口众多,能源资源相对匮乏,节约能源犹显重要。钢铁行业竞争激烈,各公司为提高自身竞争力,采用各种手段降低成本,其中最常用的手段是使用先进的设备、先进的控制技术、先进的生产工艺和规模经营。我国钢铁业消耗的能源占整个工业总量的10%,能源消耗比发达国家高15%-20%,节能不仅是企业降成本、提高产品市场竞争力的重要途径,更是企业必须承担的促进全社会资
研究性学习的目的在于改变学生以单纯地接受教师传授知识为主的学习方式,为学生构建开放的学习环境,提供多渠道获取知识、并将学到的知识综合运用于实践的机会,培养学生的创
摘要: Sigma-Delta广泛应用于高精度模数转换领域,如何快速高效的对其仿真是一个受人关注的问题。采用SIMULINK对Sigma-Delta调制器进行行为级建模与仿真,该模型考虑积分器的大部分非理想因素,包括有限直流增益、有限带宽、摆率和饱和电压等。详细介绍这些非理想因素影响和建模方法,给出实际Sigma-Delta调制器的仿真结果,证明方法的有效性。  关键词: 调制器;模型;非理想;仿
摘要: 随着特高压交流输电在我国的大力发展,其输电线路的充电功率过大的问题也日益的凸显出来,由于特高压输电的特殊性,特高压输电系统的无功补偿方式与以往熟知的无功补偿方式有较大的差异,也带来一些特殊问题,如无功补偿的电压等级、容量等都是我国所未用过的。通过对比分析常用的特高压交流输电的无功补偿技术,对特高压交流输电无功补偿的前景进行分析。  关键词: 特高压交流输电;无功补偿;MCR;TCR  中图
0 引言  随着商务、科技和政府等事务的信息化步伐加快,数据的形成速度也在加快,形成瞬间数据的爆炸性增长势态。与此同时,人们收集数据的能力也在迅速提高。现在,internet已经真正成为了一个全球的信息系统,人们都已经淹没在了数据和信息的海洋中,都在这数据的汪洋中寻找有利的信息,寻找商机,寻找利润增长点。那么,人们在海量数据中又如何才能快速获得有效数据信息呢,这就需要采用智能处理方式来发现数据中的