C#多线程通信之委托(事件)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C#多线程通信之委托(事件)
在研究C# 线程之间通信时,发现传统的方法大概有三种
①全局变量,由于同一进程下的多个进程之间共享数据空间,所以使用全局变量是最简单的方法,但要记住使用volatile进行限制。
②线程之间发送消息(这个随后文章中会讨论到)。
③CEvent为MFC中的一个对象,可以通过对CEvent的触发状态进行改变,从而实现线程间的通信和同步,这个主要是实现线程直接同步的一种方法。
本文介绍的一种方法是这三种之外的一种方法,本文中实例是通过创建一个线程类,通过委托事件把值传送到Form所在的类中,同时更新Form类中的一个控件(Label)中的值。
实现功能比较简单,目的是实现此功能,先把代码贴上:
MyThread.cs
ing System;
ing System.Threading;
3.
space ThreadsComm
5.{
6. public delegate void ReadParamEventHandler(string sParam);
7. class MyThread
8. {
9. public Thread thread1; 10. private static ReadParamEventHandler OnReadParamEvent; 11. public MyThread() 12. {
13. thread1 = new Thread(new ThreadStart(MyRead)); 14. thread1.IsBackground = true; 15. thread1.Start();
16. }
17. public event ReadParamEventHandler ReadParam 18. {
19. add { OnReadParamEvent += new ReadParamEventHandler(value);} 20. remove{ OnReadParamEvent -= new ReadParamEventHandler(value);} 21. }
22. protected void MyRead() 23. {
24. int i = 0; 25. while (true) 26. {
27. Thread.Sleep(1000);
28. i = i + 1;
29. OnReadParamEvent(i.ToString());//触发事件30. }
31. }
32. }
33.}
其中的
1.public event ReadParamEventHandler ReadParam
2. {
3. add { OnReadParamEvent += new ReadParamEventHandler(value);}
4. remove{ OnReadParamEvent -= new ReadParamEventHandler(value);}
5. }
这个需要说明一下:
add 上下文关键字用于定义一个自定义事件访问器,当客户端代码订阅您的事件时将调用该访问器。如果提供自定义add 访问器,还必须提供remove 访问器。
remove 上下文关键字用于定义一个自定义事件访问器,当客户端代码取消订阅事件时将调用该访问器。如果提供自定义remove 访问器,还必须提供add 访问器。
Form.cs
ing System;
ing System.Windows.Forms;
3.
space ThreadsComm
5.{
6. public partial class Form1 : Form
7. {
8. private static string param = ""; 9. public Form1() 10. {
11. InitializeComponent();
12. MyThread thread1 = new MyThread(); 13. thread1.ReadParam += this.OnRead; 14. }
15.
16. private void OnRead(string sParam) 17. {
18. param = sParam;
19. Object[] list = { this,System.EventArgs.Empty}; 20. this.lblShow.BeginInvoke(new EventHandler(LabelShow), list); 21. }
22. protected void LabelShow(Object o, EventArgs e) 23. {
24. this.lblShow.Text = param; 25. }
26. }
27.}
其中的,
1.MyThread thread1 = new MyThread();
2.thread1.ReadParam += this.OnRead; 是订阅线程类中的事件。
1.this.lblShow.BeginInvoke(new EventHandler(LabelShow), list);
Invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址,因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件,那么将会产生竞争条件,造成不可预料的结果。