C# 委託和事件,簡單示例說明問題

先看看示例效果c++

按照國際慣例,得先說說概念。編程

委託(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句話區分委託和事件:

一、委託通常是本身聲明,別人調用。

二、事件是本身聲明,本身調用,可是響應在別人那邊。

 

看完了這些,不要覺得你就會使用委託和事件,只能說明你看了個人文章,謝謝。

demo

相關文章
相關標籤/搜索