您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么在c#中利用委托事件實現多線程通信,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
在研究c# 線程之間通信時,發現傳統的方法大概有三種:
全局變量,由于同一進程下的多個進程之間共享數據空間,所以使用全局變量是最簡單的方法,但要記住使用volatile進行限制。
線程之間發送消息(這個隨后文章中會討論到)。
CEvent為MFC中的一個對象,可以通過對CEvent的觸發狀態進行改變,從而實現線程間的通信和同步,這個主要是實現線程直接同步的一種方法。
本文介紹的一種方法是這三種之外的一種方法,本文中實例是通過創建一個線程類,通過委托事件把值傳送到Form所在的類中,同時更新Form類中的一個控件(Label)中的值。
實現功能比較簡單,目的是實現此功能,先把代碼貼上:
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());//觸發事件 } } } }
其中的
public event ReadParamEventHandler ReadParam { add { OnReadParamEvent += new ReadParamEventHandler(value);} remove{ OnReadParamEvent -= new ReadParamEventHandler(value);} }
這個需要說明一下:
add 上下文關鍵字用于定義一個自定義事件訪問器,當客戶端代碼訂閱您的事件時將調用該訪問器。 如果提供自定義 add 訪問器,還必須提供 remove 訪問器。
remove 上下文關鍵字用于定義一個自定義事件訪問器,當客戶端代碼取消訂閱事件時將調用該訪問器。 如果提供自定義 remove 訪問器,還必須提供 add 訪問器。
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;
是訂閱線程類中的事件。
this.lblShow.BeginInvoke(new EventHandler(LabelShow), list);
Invoke或者 BeginInvoke方法都需要一個委托對象作為參數。委托類似于回調函數的地址,因此調用者通過這兩個方法就可以把需要調用的函數地址封送給界面線程。這些方法里面如果包含了更改控件狀態的代碼,那么由于最終執行這個方法的是界面線程,從而避免了競爭條件,避免了不可預料的問題。如果其它線程直接操作界面線程所屬的控件,那么將會產生競爭條件,造成不可預料的結果。
使用 Invoke完成一個委托方法的封送,就類似于使用 SendMessage方法來給界面線程發送消息,是一個同步方法。也就是說在 Invoke封送的方法被執行完畢前, Invoke方法不會返回,從而調用者線程將被阻塞。
使用 BeginInvoke方法封送一個委托方法,類似于使用 PostMessage進行通信,這是一個異步方法。也就是該方法封送完畢后馬上返回,不會等待委托方法的執行結束,調用者線程將不會被阻塞。但是調用者也可以使用 EndInvoke方法或者其它類似 WaitHandle機制等待異步操作的完成。
但是在內部實現上, Invoke和 BeginInvoke都是用了 PostMessage方法,從而避免了 SendMessage帶來的問題。而 Invoke方法的同步阻塞是靠 WaitHandle機制來完成的。
上述內容就是怎么在c#中利用委托事件實現多線程通信,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。