从刚接触c#编程到现在,差不多快有一年的时间了。在学习过程中,有很多地方始终似是而非,直到最近才弄明白。

本文将先介绍用法,后评断功能。

一、委托

基本用法:

1.声明一个委托类型。委托就像是‘类'一样,声明了一种委托之后就可以创建多个具有此种特征的委托。(特征,指的是返回值、参数类型)

public delegate void SomeKindOfDelegate(string result);

2.创建一个在1中创建的委托类型的委托。

public SomeKindOfDelegate aDelegate;

3.为2中创建的具体的委托添加响应函数。响应函数必须符合1中的‘特征'。

aDelegate +=new SomeKindOfDelegate(aFunctionThatJustForDelegate);
private void aFunctionThatJustForDelegate(string result)
{
  MessageBox.Show(result);
}

4.完成以上三步之后,就可以使用Invoke来对委托进行调用了。Invoke可以选择调用的目标函数,调用优先级,以及调用的参数。

aDelegate.BeginInvoke("Hello~I'm being invoked!", null, null);

上面是基本用法,除了这种基本用法之外,还可以结合var、匿名委托、lambda委托等方法。

完整代码:

namespace wtfIsDelegate
{
public delegate void SomeKindOfDelegate(string result);
public partial class Form1 : Form
{
public event SomeKindOfDelegate aDelegate;
public Form1()
{
InitializeComponent();
aDelegate +=new SomeKindOfDelegate(aFunctionThatJustForDelegate);
aDelegate.BeginInvoke("Hello~I'm being invoked!", null, null);
}
private void btnDelegate_Click(object sender, EventArgs e)
{
}
private void aFunctionThatJustForDelegate(string result)
{
MessageBox.Show(result);
}
}
}

委托的用处:

委托的优点,是可以实现异步(BeginInvoke),还可以在某种需要同时调用多个同参数、返回值的情况下简化代码。

二、事件

基本用法:

1.定义委托。

public delegate void SomeKindOfDelegate(string result);

2.定义事件。

public event SomeKindOfDelegate aDelegate;

3.为事件添加响应函数。

process.Exited += new EventHandler(CmdProcess_Exited);

4.为事件规定触发(调用)方式。(【也可以没有触发方式,直接invoke】)

解说:

C#里,每一种‘事件Event'大概都对应着其‘事件处理者EventHandler'。比如Process类的OutputDataReceived事件对应着DataReceivedEventHandler,对于非特异性的‘事件',比如PasswordChanged 这种,它们统一都对应着RoutedEventHandler或者EventHandler这种较为通用的‘事件处理者'。然而,‘EventHandler'也只是充当了一个中介的角色,真正触发了‘Event'之后要做什么,还需要我们手动指定,像这样:

process.Exited += new EventHandler(CmdProcess_Exited); // 注册进程结束事件 。

EventHandler本来也是委托。比如

public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e);

自定义事件

自定义事件是一种类似于委托的方式,

自定义事件某种意义上改变了程序的流程,使得某个条件的变化由‘不断查询'转变为‘订阅与处理'的关系。

自定义事件需要有以下几个元素:

事件的发起者,事件的订阅,以及事件的处理程序。从发起者到处理程序之间是可以传参数的。

一个事件的‘发起'可以依赖于某种系统消息,比如‘OnKeyDown'、‘OnMouseClick'(【我目前还没见过这么写的源码】),也可以在某个条件达成时(比如两次输入了同样的字符)自行调用(其实收到系统消息也算是‘条件达成')。【更多的event是这么写出来的】

有些事件,并没有明显的‘发起者'。

委托和事件是啥关系

委托和自定义事件的使用方式十分十分类似。event 只有类的内部可以 Invoke,delegate的话,在哪都可以Invoke。调用的方式貌似也略有区别(传参方式)

由于调用方式和传参的差异,event显得更保守/稳定一些。event也更容易从‘理解'上更容易接受。

delegate貌似更多的用于进行异步(begin invoke)。而event则更多的用来做自定义事件。

委托和异步是啥关系

异步是委托可以实现的一种功能(或者叫做‘现象'也可以) 异步可以由很多种其他方式体现,比如多线程(thread,threadpool,task等等)。

**********转载:https://m.jb51.net/article/109334.htm

浅谈C#中的委托、事件与异步的更多相关文章

  1. 浅谈JavaScript中的事件

    引言 Html页面与JavaScript之间的交互是通过事件来完成的.事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(处理程序)来预订事件,以便事件发生时执行相应的代码.这在传 ...

  2. 浅谈Android中的事件分发机制

    View事件分发机制的本质就是就是MotionEvent事件的分发过程,即MotionEvent产生后是怎样在View之间传递及处理的. 首先介绍一下什么是MotionEvent.所谓MotionEv ...

  3. 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)

    [分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...

  4. 浅谈HTTP中GET、POST用法以及它们的区别

    浅谈HTTP中GET.POST用法以及它们的区别 HTTP定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符.我们可以这样认为: 一 ...

  5. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

  6. 浅谈 .NET 中的对象引用、非托管指针和托管指针 理解C#中的闭包

    浅谈 .NET 中的对象引用.非托管指针和托管指针   目录 前言 一.对象引用 二.值传递和引用传递 三.初识托管指针和非托管指针 四.非托管指针 1.非托管指针不能指向对象引用 2.类成员指针 五 ...

  7. Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

    Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...

  8. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  9. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

随机推荐

  1. phpmailer邮件类

    <?php/** * 邮件类 * Enter description here ... * @author df * Mail::getMail()->sendMail(); * */cl ...

  2. 可变、不可变数据类型和hash

    一.可变和不可变数据类型 在python中,我们对数据类型除了分为数字类型.字符串类型.列表类型.元组类型.字典类型和集合类型外, 还有另外一种分类方式,我们给数据类型分为可变数据类型和不可变数据类型 ...

  3. Game Develop Books

    [Working On] [Pending] 3.<实时计算机图形学> 4.<游戏编程精粹1> 5.<游戏编程精粹2> 6.<3D游戏引擎设计:实时计算机图形 ...

  4. linux su su -

    本人以前一直习惯直接使用root,很少使用su,前几天才发现su与su -命令是有着本质区别的! 大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行, ...

  5. Professional C# 6 and .NET Core 1.0 - Creating Hello, World! with Visual Studio

    本文为转载,学习研究 Creating Hello, World! with Visual Studio Chapter 1, “.NET Application Architectures,” ex ...

  6. Java Http 请求

    package zr.weixin.com.utils; import java.io.BufferedReader; import java.io.IOException; import java. ...

  7. oracle plsql参数

    declare inst_name varchar2(100); cursor mycur is select * from tran_forward t where t.instrument_typ ...

  8. Requests接口测试(五)

    使用python+requests编写接口测试用例 好了,有了前几章的的基础,写下来我把前面的基础整合一下,来一个实际的接口测试练习吧. 接口测试流程 1.拿到接口的URL地址 2.查看接口是用什么方 ...

  9. Oracle 写存储过程的一个模板还有一些基本的知识点

    我很少用Oracle,也算新手,不过其实入手没有那么难,下面只是一个基本知识,高手绕道,其实数据库基本是相同的,这里提供都是基本知识点 有一个Oracle溢出的问题,容易让新手怀疑到无所怀疑,其实就是 ...

  10. 接上一篇,Springcloud使用feignclient远程调用服务404 ,为什么去掉context-path后,就能够调通

    一.问题回顾 如果application.properties文件中配置了 #项目路径 server.servlet.context-path=/pear-cache-service 则feigncl ...