先看看示例效果c++
按照國際慣例,得先說說概念。編程
事件(C# 編程指南)多線程
以上內容來自MSDN。app
委託源碼異步
概念和代碼都有了。剩下的就是應用了,要是隻知道概念不會用,那仍是等於不會。ide
要用委託首先要明確幾個問題:函數
一、爲何須要委託?什麼場合用?ui
我也不想使用委託,誰沒事想多些代碼。可是在某一天,我寫代碼的時候,在多線程中訪問了 UI 控件,發現不行。因而乎百度一大堆,結果就是用委託。官方也有這樣的Demo,具體本身百度。因而乎獲得一個答案,多線程訪問 UI 控件得藉助委託。其餘的場景不說了,其實大部分都是多線程和異步的場景須要。到這裏咱們就明白了,委託這東西,能夠在多線程或者異步操做中發揮大做用,能夠在窗體間傳參,並且還很安全。spa
二、怎麼使用?
委託的使用也是比較容易的。
1)、定義委託
2)、聲明委託對象
3)、實例化委託
4)、調用委託(執行方法)
來點實際的代碼,多線程中訪問 UI 控件:
public delegate void UpdateTextEventHandler(string strText); // 一、定義委託類型 public UpdateTextEventHandler UpdateText; // 二、聲明委託對象public FrmMain() { InitializeComponent(); UpdateText = OnUpdateText; // 三、實例化委託對象,這裏編譯後就不是這樣子了,而是有個 new 操做 } private void OnUpdateText(string strText) { labTest.Text = strText; } private void btnThreadOperateControl_Click(object sender, EventArgs e) { new Task(() => { // 這裏就不得不使用委託了,不然會報錯,提示大概意思就是「不能再其餘線程訪問控件" for (int i = 0; i < 1000; i++) { // 自定義委託方式 //Invoke(UpdateText, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); // 採用泛型委託簡化後 Invoke(new Action<string>(strText => labTest.Text = strText), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); System.Threading.Thread.Sleep(10); } }).Start(); }
以上代碼比較簡單,但能夠解決一些基本的多線程訪問控件問題。現實場景有:後臺多線程操做業務,打印操做日誌到主界面Text框。後臺採集數據,更新到主界面Chart。
固然,委託做爲C#的一個很核心的東西,遠不止這些內容。有多播委託,將委託做爲函數參數進行封裝等。
委託相似:c/c++中的函數指針封裝版,MFC/C++Builder中的PostMessage/SendMessage封裝版,Qt中的信號槽。
一道華麗的分割線
使用事件也要弄清楚幾個問題
一、爲何使用委託?什麼場合用?
事件是對多播委託的一個封裝,主要是限制誰發佈事件,誰觸發。好比本身定義一個類,類裏面有個事件,那麼只能你來觸發,響應在別人那邊。事件多用於UI操做,但不表明非UI不可使用。窗體程序將這一點體現的淋漓盡致。
二、怎麼使用?
事件的使用也是比較容易的。
一、因爲事件是基於委託的,那麼你得先定義一個委託類型
二、聲明委託對象,並用event關鍵字修飾
三、在聲明事件的類內部使用(誰聲明的,誰觸發)
四、在聲明事件的類的外部綁定(沒有聲明的,那你就來訂閱(綁定 +=)事件)
來點實際代碼:
using System; namespace EventDemo { public delegate void TestEventHandler(); class Program { static void Main(string[] args) { Class1 class1 = new Class1(); class1.Test1 = Test; // 委託調用,這裏表明是Program類調用class1.Test1(),可不能理解成class1調用 class1.Test1(); class1.Test += Test; // 事件調用,這裏對事件的體現不是很明顯,由於能看到調用了DoSomething。 // 雖然調用了DoSomething,可是事件是在Class1內部調用的 class1.DoSomething(); Console.WriteLine("Press any key to close the application..."); Console.ReadKey(true); } static void Test() { Console.WriteLine("hello world."); } } class Class1 { public TestEventHandler Test1; // 聲明委託對象 public event TestEventHandler Test; // 聲明事件對象 public void DoSomething() { Test?.Invoke(); } } }
我的經驗分享2句話區分委託和事件:
一、委託通常是本身聲明,別人調用。
二、事件是本身聲明,本身調用,可是響應在別人那邊。
看完了這些,不要覺得你就會使用委託和事件,只能說明你看了個人文章,謝謝。