当前位置 > 首页 > 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