当前位置 > 首页 > Asp.net

Net线程间通信的异步机制

2012-7-2 9:21:00来源:Asp.net

线程间通信

我们看下面的图

图1

我们来看线程间通信的原理:线程(Thread B)和线程(Thread A)通信, 首先线程A 必须实现同步上下文对象(Synchronization Context), 线程B通过调用线程A的同步上下文对象来访问线程A,所有实现都是在同步上下文中完成的.线程B有两种方式来实现线程间的通信.

第一种:调用线程A的同步上下文对象,阻碍当前线程,执行红色箭头调用,直到黄色箭头返回(同步上下文执行完毕)才释放当前线程. (1->2->3->5)

第二种: 调用线程A的同步上下文对象(实际上是在开启一个新线程去执行,1->2->3->5) ,执行红色箭头,但并不阻碍当前线程(原有线程,1->4->5),绿色箭头继续执行.

文章中将会通过下面几个类来进行介绍:

ISynchronizeInvoke 接口

SynchronizationContext 类

AsyncOperation / AsyncOperationManager 类

1. ISynchronizeInvoke 接口

我们先来看下面一段异步的代码(Window Form控件下有1个Button/1个Label),但点击Button的时候,执行异步调用,完成后,告诉Window Form的 Label控件Text属性” Asynchronous End”.

Code1.1

1 delegate void DoWork();
2 private void button1_Click(object sender, EventArgs e)
3 {
4 //辅助方法,查看当前线程
5 Debug.WriteLine(string.Format("Window Form Method.Thread ID:#{0}",
6 Thread.CurrentThread.ManagedThreadId));
7  //Label lblStatus 属于主线程的控件[1]
8  this.lblStatus.Text = "Asynchronous Start.";
9  //使用委托来调用异步方法
10  DoWork work = DoWorkMethod;
11 work.BeginInvoke(OnWorkCallback, work);
12 }
13 void OnWorkCallback(IAsyncResult asyncResult)
14 {
15 //辅助方法,查看当前线程
16 Debug.WriteLine(string.Format("Asynchronous Callback Method.Thread ID:#{0}",
17 Thread.CurrentThread.ManagedThreadId));
18 DoWork work = asyncResult.AsyncState as DoWork;
19 if (work != null)
20 {
21 work.EndInvoke(asyncResult);
22 }
23 // 报错:"线程间操作无效: 从不是创建控件“lblStatus”的线程访问它."
24 this.lblStatus.Text = "Asynchronous End"; //上面注释[1]
25 }
26
27 void DoWorkMethod()
28 {
29 Thread.Sleep(3000);//模拟耗时工作
30 }

运行代码,我们在第22行报错(异步方法体内).为什么呢?我们必须清楚的一点,在windows应用窗体应用程序中,对窗体上控件属性的任何修改都必须在主线程中完成。不能从其他线程安全地访问控件的方法和属性。从Debug窗口中我们也可以看出(图1.1).执行Button Click事件的时候,运行在线程ID =#10; 在异步的方法体内,运行在线程ID=#7.不同线程间不能直接通信.

为了解决这个问题,实现图1.1 中 #10 和 #7 的通信,下来开始认识ISynchronizeInvoke 接口(此接口来自.Net Framework 1.0),提供3个方法1个属性:

BeginInvoke / EndInvoke 方法 : 异步方法

Invoke 方法 : 同步方法

InvokeRequired 属性 : 判读来源的执行线程

下面我们看Code1.2的具体代码来说明(对Code1.1改写,其中Label 改为ListBox)

1 delegate void DoWork();
2  private void button1_Click(object sender, EventArgs e)
3  {
4  

  • XamlPad小程序

    2007-7-10 10:02:00

    摘要: 闲着没事,仿照SDK的样子自己做了一个。 程序主要使用了System.Windows.Markup命名空间下的XamlReader类和XamlWriter,其中XamlReader可

  • 利用img和div标签实现图像下拉列表的模拟

    2009-6-11 10:06:00

    摘要: dropdownlist本身不支持图像列表,那么我们利用jquery来实现下拉列表的模拟。 -----------------------------------------------

  • 分享我的戒烟经验

    2009-11-14 13:17:00

    阅读: 379 评论: 32 作者: mikelij 发表于 2009-11-14 09:51 原文链接 戒烟对于烟民来说真是一件挺难的事情。没有经历的人真的难以体会。 我现在已经戒

  • ASP.NET Web API: Extending content negotiation with new formats

    2012-4-20 17:07:00

    My last post about ASP.NET Web API content negotiation support gave you basic idea about what con

  • 如何实施好基于MOSS的企业搜索项目(上)

    2009-12-3 3:35:00

    【时间飞逝,在博客堂也常驻了6年多了。有感于经常有人反映说博客很久没更新了,加上近期确实也想把前几年做过的大大小小二三十个项目做个总结。于是决心每个月都花点时间来写点东西,长篇或随笔都好。前些日子讲

  • 工作流 - 架构描述

    2009-12-11 22:45:00

    阅读: 235 评论: 0 作者: 快乐学习 发表于 2009-12-11 20:31 原文链接 几年前做个工作流相关的一些工作,感兴趣的可参考一下。 本文档是工作流主体部

  • 彻底杜绝PHP的session cookie错误

    2009-5-22 13:15:00

    本文讨论的是如何彻底杜绝warning: Cannot add header information - headers already sent in...... 这种令人莫明其妙的的错误。

  • Using jQuery Grid With ASP.NET MVC

    2009-4-15 8:18:00

    Continuing in my pseudo-series of posts based on my ASP.NET MVC Ninjas on Fire Black Belt Tips Pres

  • 【译著】20章 jQuery — 精通ASP.NET MVC 3

    2012-8-20 15:15:00

    说明1: 本书的文字翻译工作已经完成,目前正处于出版社审核阶段,具体出版日期已经不是我决定的事情了。感谢园友对此书的广泛关注,这里贴出第20章内容。 说明2: 本园博主 牧童 先生已经贴出了本章的

  • 在.NET 1.1下实现WebResource.axd

    2007-7-27 18:03:00

    摘要: 见到好多人在网上问起在.NET 1.1下如何实现类似.NET 2.0中的WebResource.axd,做了一下,以下是实现代码: HttpWebResourceHandlerCode hi