先看看示例效果

按照国际惯例,得先说说概念。

委托(C# 编程指南)

事件(C# 编程指南)

以上内容来自MSDN。

委托源码

【委托】

概念和代码都有了。剩下的就是应用了,要是只知道概念不会用,那还是等于不会。

要用委托首先要明确几个问题:

1、为什么需要委托?什么场合用?

  我也不想使用委托,谁没事想多些代码。但是在某一天,我写代码的时候,在多线程中访问了 UI 控件,发现不行。于是乎百度一大堆,结果就是用委托。官方也有这样的Demo,具体自己百度。于是乎得到一个答案,多线程访问 UI 控件得借助委托。其他的场景不说了,其实大部分都是多线程和异步的场景需要。到这里我们就明白了,委托这东西,可以在多线程或者异步操作中发挥大作用,可以在窗体间传参,而且还很安全。

2、怎么使用?

  委托的使用也是比较容易的。

  1)、定义委托

  2)、声明委托对象

  3)、实例化委托

  4)、调用委托(执行方法)

来点实际的代码,多线程中访问 UI 控件:

public delegate void UpdateTextEventHandler(string strText); // 1、定义委托类型

        public UpdateTextEventHandler UpdateText; // 2、声明委托对象public FrmMain()
{
InitializeComponent(); UpdateText = OnUpdateText; // 3、实例化委托对象,这里编译后就不是这样子了,而是有个 new 操作
} private void OnUpdateText(string strText)
{
labTest.Text = strText;
} private void btnThreadOperateControl_Click(object sender, EventArgs e)
{
new Task(() =>
{
// 这里就不得不使用委托了,否则会报错,提示大概意思就是“不能再其他线程访问控件"
for (int i = ; i < ; 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();
}
}).Start();
}

以上代码比较简单,但可以解决一些基本的多线程访问控件问题。现实场景有:后台多线程操作业务,打印操作日志到主界面Text框。后台采集数据,更新到主界面Chart。

当然,委托作为C#的一个很核心的东西,远不止这些内容。有多播委托,将委托作为函数参数进行封装等。

委托类似:c/c++中的函数指针封装版,MFC/C++Builder中的PostMessage/SendMessage封装版,Qt中的信号槽。

一道华丽的分割线


【事件】

使用事件也要弄清楚几个问题

1、为什么使用委托?什么场合用?

  事件是对多播委托的一个封装,主要是限制谁发布事件,谁触发。比如自己定义一个类,类里面有个事件,那么只能你来触发,响应在别人那边。事件多用于UI操作,但不代表非UI不可以使用。窗体程序将这一点体现的淋漓尽致。

2、怎么使用?

  事件的使用也是比较容易的。

  1、由于事件是基于委托的,那么你得先定义一个委托类型

  2、声明委托对象,并用event关键字修饰

  3、在声明事件的类内部使用(谁声明的,谁触发)

  4、在声明事件的类的外部绑定(没有声明的,那你就来订阅(绑定 +=)事件)

来点实际代码:

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句话区分委托和事件:

1、委托一般是自己声明,别人调用。

2、事件是自己声明,自己调用,但是响应在别人那边。

看完了这些,不要以为你就会使用委托和事件,只能说明你看了我的文章,谢谢。

demo

C# 委托和事件,简单示例说明问题的更多相关文章

  1. C#委托与事件--简单笔记

    委托 简单记录点东西 适合似懂非懂的朋友看看 委托类型用来定义和响应应用程序中的回调. 借此可以设计各种有面向对象特性的代码模式.下面要说的事件在我看来就是委托的一种实现,再深一步讲,利用委托加事件, ...

  2. [转载]C#委托与事件--简单笔记

    原文地址:https://www.cnblogs.com/joeymary/p/8486358.html 委托 简单记录点东西 适合似懂非懂的朋友看看委托类型用来定义和响应应用程序中的回调.借此可以设 ...

  3. C#委托与事件的简单使用

    前言:上一篇博文从原理和定义的角度介绍了C#的委托和事件.本文通过一个简单的小故事,来说明C#委托与事件的使用方法及其方便之处. 在阅读本文之前,需要你对委托和事件的基本概念有所了解.如果你是初次接触 ...

  4. C# 委托和事件(一):最简单的委托和事件

    C#的事件基于委托,所以先说委托. 一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手.所以我需要一个实际的场景. 明天刚好考试(商务英语),考试上有两个角色(class):老师( ...

  5. 简单理解和使用 C# 委托与事件

    委托和事件 委托:委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程 ...

  6. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  7. [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

    原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...

  8. C#之委托与事件

    委托与事件 废话一堆:网上关于委托.事件的文章有很多,一千个哈姆雷特就有一千个莎士比亚,以下内容均是本人个人见解. 1. 委托 1.1 委托的使用 这一小章来学习一下怎么简单的使用委托,了解一些基本的 ...

  9. [ASP.NET MVC 大牛之路]02 - C#高级知识点概要(1) - 委托和事件

    在ASP.NET MVC 小牛之路系列中,前面用了一篇文章提了一下C#的一些知识点.照此,ASP.NET MVC 大牛之路系列也先给大家普及一下C#.NET中的高级知识点.每个知识点不太会过于详细,但 ...

随机推荐

  1. C++的编译与连接

    编译器的任务是把我们人类通常能够读懂的文本形式的 C 语言文件转化成计算机能明白的目标文件.1.  预编译生成的仍然是.c文件1)把"include"的文件拷贝到要编译的源文件中. ...

  2. asp.net后台解析JSON,并将值赋给对象

    示例代码如下: using System; using System.Collections.Generic; using System.Web.Script.Serialization; publi ...

  3. python中的&&及||

    首先说明一下,在python中是没有&&及||这两个运算符的,取而代之的是英文and和or.其他运算符没有变动. 接着重点要说明的是python中的a.any(),我之所以会涉及到这个 ...

  4. 【校招面试 之 剑指offer】第10-2题 青蛙跳台阶问题

    题目1:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶.求该青蛙跳上一个n级台阶共有多少种跳法? 题目2:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶...也可以一次跳n级台阶.求该青蛙跳上一个 ...

  5. centos7.5配置双网卡上网

    一.环境及说明 当初有这个需求,主要是帮一个高校的客户搭建一个大数据集群,使用的是校园网,交换机上一个端口只能连接一部电脑上网,不能通过路由组建子网,确保集群中的服务器有子网ip的同时,也能够通过公网 ...

  6. [leetcode]238. Product of Array Except Self除了自身以外的数组元素乘积

    Given an array nums of n integers where n > 1,  return an array output such that output[i] is equ ...

  7. 3-QT程序运行时报错E:\SogouInput\6.7.0.0329\程序异常终止,该怎么解决?

    https://bbs.csdn.net/topics/390653779 出现这个错误的原因,使用声明的对象时,没有使用new对对象进行实例化. 包括:数组.

  8. 深入php内核,从底层c语言剖析php实现原理

    深入php内核,从底层c语言剖析php实现原理 非常好的电子书:http://www.cunmou.com/phpbook/preface.md   这是它的目录: PHP的生命周期 让我们从SAPI ...

  9. lib文件反汇编

    运行vc命令行,输入:dumpbin /disasm xxx.lib > test.txt lib就是obj文件打包起来的,可以用lib.exe解出来,下面是vc环境下的操作,其他环境,看命令行 ...

  10. Laravel 5.x 启动过程分析

     Posted on 2015年9月11日 by  学院君 1.初始化Application 1.1 注册基本绑定 app -> Application实例(Illuminate\Foundat ...