c#多線程通信之委托事件
在研究c# 線程之間通信時(shí),發(fā)現(xiàn)傳統(tǒng)的方法大概有三種:
- 全局變量,由于同一進(jìn)程下的多個(gè)進(jìn)程之間共享數(shù)據(jù)空間,所以使用全局變量是最簡(jiǎn)單的方法,但要記住使用volatile進(jìn)行限制。
- 線程之間發(fā)送消息(這個(gè)隨后文章中會(huì)討論到)。
- CEvent為MFC中的一個(gè)對(duì)象,可以通過(guò)對(duì)CEvent的觸發(fā)狀態(tài)進(jìn)行改變,從而實(shí)現(xiàn)線程間的通信和同步,這個(gè)主要是實(shí)現(xiàn)線程直接同步的一種方法。
本文介紹的一種方法是這三種之外的一種方法,本文中實(shí)例是通過(guò)創(chuàng)建一個(gè)線程類(lèi),通過(guò)委托事件把值傳送到Form所在的類(lèi)中,同時(shí)更新Form類(lèi)中的一個(gè)控件(Label)中的值。
實(shí)現(xiàn)功能比較簡(jiǎn)單,目的是實(shí)現(xiàn)此功能,先把代碼貼上:
MyThread.cs
using System;
using System.Threading;
namespace ThreadsComm
{
public delegate void ReadParamEventHandler(string sParam);
class MyThread
{
public Thread thread1;
private static ReadParamEventHandler OnReadParamEvent;
public MyThread()
{
thread1 = new Thread(new ThreadStart(MyRead));
thread1.IsBackground = true;
thread1.Start();
}
public event ReadParamEventHandler ReadParam
{
add { OnReadParamEvent += new ReadParamEventHandler(value);}
remove{ OnReadParamEvent -= new ReadParamEventHandler(value);}
}
protected void MyRead()
{
int i = 0;
while (true)
{
Thread.Sleep(1000);
i = i + 1;
OnReadParamEvent(i.ToString());//觸發(fā)事件
}
}
}
}
其中的
public event ReadParamEventHandler ReadParam
{
add { OnReadParamEvent += new ReadParamEventHandler(value);}
remove{ OnReadParamEvent -= new ReadParamEventHandler(value);}
}
這個(gè)需要說(shuō)明一下:
add 上下文關(guān)鍵字用于定義一個(gè)自定義事件訪問(wèn)器,當(dāng)客戶端代碼訂閱您的事件時(shí)將調(diào)用該訪問(wèn)器。 如果提供自定義 add 訪問(wèn)器,還必須提供 remove 訪問(wèn)器。
remove 上下文關(guān)鍵字用于定義一個(gè)自定義事件訪問(wèn)器,當(dāng)客戶端代碼取消訂閱事件時(shí)將調(diào)用該訪問(wèn)器。 如果提供自定義 remove 訪問(wèn)器,還必須提供 add 訪問(wèn)器。
Form.cs
using System;
using System.Windows.Forms;
namespace ThreadsComm
{
public partial class Form1 : Form
{
private static string param = "";
public Form1()
{
InitializeComponent();
MyThread thread1 = new MyThread();
thread1.ReadParam += this.OnRead;
}
private void OnRead(string sParam)
{
param = sParam;
Object[] list = { this,System.EventArgs.Empty};
this.lblShow.BeginInvoke(new EventHandler(LabelShow), list);
}
protected void LabelShow(Object o, EventArgs e)
{
this.lblShow.Text = param;
}
}
}
其中的
MyThread thread1 = new MyThread(); thread1.ReadParam += this.OnRead;
是訂閱線程類(lèi)中的事件。
this.lblShow.BeginInvoke(new EventHandler(LabelShow), list);
Invoke或者 BeginInvoke方法都需要一個(gè)委托對(duì)象作為參數(shù)。委托類(lèi)似于回調(diào)函數(shù)的地址,因此調(diào)用者通過(guò)這兩個(gè)方法就可以把需要調(diào)用的函數(shù)地址封送給界面線程。這些方法里面如果包含了更改控件狀態(tài)的代碼,那么由于最終執(zhí)行這個(gè)方法的是界面線程,從而避免了競(jìng)爭(zhēng)條件,避免了不可預(yù)料的問(wèn)題。如果其它線程直接操作界面線程所屬的控件,那么將會(huì)產(chǎn)生競(jìng)爭(zhēng)條件,造成不可預(yù)料的結(jié)果。
使用 Invoke完成一個(gè)委托方法的封送,就類(lèi)似于使用 SendMessage方法來(lái)給界面線程發(fā)送消息,是一個(gè)同步方法。也就是說(shuō)在 Invoke封送的方法被執(zhí)行完畢前, Invoke方法不會(huì)返回,從而調(diào)用者線程將被阻塞。
使用 BeginInvoke方法封送一個(gè)委托方法,類(lèi)似于使用 PostMessage進(jìn)行通信,這是一個(gè)異步方法。也就是該方法封送完畢后馬上返回,不會(huì)等待委托方法的執(zhí)行結(jié)束,調(diào)用者線程將不會(huì)被阻塞。但是調(diào)用者也可以使用 EndInvoke方法或者其它類(lèi)似 WaitHandle機(jī)制等待異步操作的完成。
但是在內(nèi)部實(shí)現(xiàn)上, Invoke和 BeginInvoke都是用了 PostMessage方法,從而避免了 SendMessage帶來(lái)的問(wèn)題。而 Invoke方法的同步阻塞是靠 WaitHandle機(jī)制來(lái)完成的。
想實(shí)驗(yàn)的讀者可以建一個(gè)winform工程,采用上邊的代碼試驗(yàn)一下。
以上就是c#多線程通信之委托事件的詳細(xì)內(nèi)容,更多關(guān)于c#多線程委托事件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c# StringBuilder.Replace 方法 (Char, Char, Int32, Int32)
c# StringBuilder.Replace 方法 (Char, Char, Int32, Int32)...2007-08-08
解析從源碼分析常見(jiàn)的基于Array的數(shù)據(jù)結(jié)構(gòu)動(dòng)態(tài)擴(kuò)容機(jī)制的詳解
本篇文章是對(duì)從源碼分析常見(jiàn)的基于Array的數(shù)據(jù)結(jié)構(gòu)動(dòng)態(tài)擴(kuò)容機(jī)制進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
WPF+Canvas實(shí)現(xiàn)平滑筆跡的示例代碼
這篇文章主要介紹了如何利用WPF+Canvas實(shí)現(xiàn)平滑筆跡效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下2022-09-09
C# HttpClient Cookie驗(yàn)證解決方法
本文將詳細(xì)介紹C# HttpClient Cookie驗(yàn)證解決方法,需要了解的朋友可以參考下2012-11-11
winform c#中子窗體關(guān)閉刷新父窗體的實(shí)例
下面小編就為大家?guī)?lái)一篇winform c#中子窗體關(guān)閉刷新父窗體的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
C#?基于NAudio實(shí)現(xiàn)對(duì)Wav音頻文件剪切(限PCM格式)
本文主要介紹了C#基于NAudio工具對(duì)Wav音頻文件進(jìn)行剪切,可以將一個(gè)音頻文件剪切成多個(gè)音頻文件(限PCM格式),感興趣的小伙伴可以學(xué)習(xí)一下2021-11-11
unity實(shí)現(xiàn)延遲回調(diào)工具
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)延遲回調(diào)工具,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
基于WinForm+Halcon實(shí)現(xiàn)圖像縮放與交互功能
本文主要講述在 WinForm 中結(jié)合 Halcon 實(shí)現(xiàn)圖像縮放、平移及實(shí)時(shí)顯示灰度值等交互功能,包括初始化窗口的不同方式,以及通過(guò)特定事件添加相應(yīng)功能的詳細(xì)步驟和代碼示例,能提升圖像處理應(yīng)用的開(kāi)發(fā)效率和用戶體驗(yàn),需要的朋友可以參考下2025-01-01

