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

  • 深入了解CLR异常处理机制

    2009-12-4 0:13:00

    阅读: 174 评论: 7 作者: 金旭亮 发表于 2009-12-03 22:01 原文链接 深入了解 CLR 异常处理机制 CLR 实现的异常处理具有以下特点:

  • VGA timing information

    2009-11-28 20:20:00

    阅读: 87 评论: 0 作者: Homography Matrix 发表于 2009-11-28 18:32 原文链接 VGA timing information from

  • Express SKU Support

    2007-4-3 5:03:00

    I have recently uploaded TestDriven.NET 2.5 Beta. This version now supports all versions of Vis

  • 对于.Net中C#指针的研究

    2011-7-28 12:07:00

    在C/C++中,对于指针的使用是很普遍的,可以这么说,如果没有指针的运用,都不知道程序如何来写。在.Net中,同样也是可以使用指针的,不过必须通过开启不安全的代码来使用。在默认情况下,新建的项目是不

  • Windows Vista Tip (01) : 快速切换日历

    2007-7-1 0:25:00

    本系列归类在“细节”,都是经过实践证明受人欢迎却多人未知的点点滴滴。应该适用于Windows Vista的所有版本,虽然只在英文版的Business和Ultimate下得到确认。 在Windo

  • ASP.NET中登录后反复跳转回登录页面

    2012-7-3 12:52:00

    项目放在新配的服务器上,在服务器上打开浏览网站一切正常,也就没怎么注意,然后准备在局域网访问进行测试,测试问题来了怎么都登录不进去,明明登陆成功都将要跳到首页了却又跳到登录页了,第一时间想到的是Fo

  • 。net学习基础之gridView的使用

    2011-4-15 7:00:00

    1.绑定 前台 : < asp : GridView ID =gvUpdateGift run

  • 模式人生-从生活中的点点滴滴认识设计模式3-单件模式(Singleton Pattern)

    2009-7-25 1:12:00

    从生活中的点点滴滴认识设计模式系列(三) 单件模式(Singleton Pattern) “老樊,你这次去山西出差得多久啊?”小

  • 基于.NET三种Ajax技术的运用——原生js、ASP.NET Ajax和.NET回调技术

    2011-9-30 12:00:00

    在进行ASP.NET开发时,我们需要用越来越多的Ajax技术,以丰富用户交互界面,不断提高用户体验。   第一种方式是我们亲自手动编写Javascript代码实现,关于这个方式我前面有一篇博文

  • 认识 yueue.ADOKeycap 开源数据库组件 - 最新发布

    2007-5-19 18:29:00

    摘要: ADOKeycap 是一个.net 2.0 下的数据库组件,它对.net 2.0下的数据库连接,数据库命令,数据库管理等进行了封装,从而简化了操作,提升了开发效率. 使用ADOKeycap开