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

相关文章
相关标签/搜索