博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
委托与事件
阅读量:5926 次
发布时间:2019-06-19

本文共 2156 字,大约阅读时间需要 7 分钟。

1.什么是委托?

  委托是表示方法的类型。

2.定义委托

Delegate int Del(int a);  //定义委托
//定义委托实例Del del;                  //Del类型的委托EventHandle handle;       //void(object,EventArgs)类型的委托Action action;            //void()类型的委托Action
action; //泛型委托 void(int)类型的委托Func
func; //泛型委托 int()类型的委托Func
func; //泛型委托 int(string)类型的委托

3.执行委托

//同步执行,会阻塞线程action(args);action.Invoke(args);//异步执行,不会阻塞线程action.BeginInvoke(args);  //EndInvoke(agrs)返回委托执行结果,但是会等待,可通过传入回调函数的方法解决等待问题。

4.什么是事件?

  事件是对委托的封装,类似于private的委托,但在类外部可以使用+=方法注册事件。

  事件的出现可以降低程序的耦合度,事件理应由事件拥有者触发,而public的委托可以在类的外部被调用者触发,事件的特性是能在外部注册,不能触发。

  事件的写法就是在委托前加event关键字

public event Del del;public event Action
action;public EventHandle
Handle;

5.单播委托

  只注册了一个方法,使用=赋值。

Action action = Method;  //注册委托action.Invoke();  //同步执行action.beginInvoke(args);  //异步执行

6.多播委托

  有多个注册方法,使用=/+=注册。

Action action = Method1;  //注册Action action += Method2;  //注册action.Invoke();  //同步执行Method1和Method2action.BeginInvoke(args);  //异步执行会报错//正确的异步执行多播委托方法if(action != null){    Delegete[] list = action.GetInvocationList();  //返回注册列表    foreach(Delegate del in list)    {        Action ac = (Action)del;        ac.BeginInvoke(args);      }}

7.带有返回值的委托

  ①单播委托

    action.Invoke()同步执行,

    IAsyncResult ar = action.BeginInvoke(args)异步执行

    int re = action.EndInvoke(ar)得到结果

  ②多播委托

    会返回最后一个委托的值,可通过遍历委托列表解决

    使用GetInvocationList()方法获得委托列表

8.如何让事件只允许一个方法注册

  解决方法是:将事件写成private,再写一个public的注册方法(使用 = 注册),一个public的取消注册方法(使用 -= 取消注册)  

private event Action action;public void Register(Action ac){        action = ac; //=是关键,覆盖注册}pub void UnRegister(Action ac){       action -= ac;}

9.注册方法(订阅者)执行出现异常怎么处理

  采用try-catch捕获,并用GetInvocationList()获取委托列表分开执行,这样可以保证在一个异常出现时,不回影响其它订阅方法的执行。

//触发事件的方法void Method(){    if(action != null)    {        Delegate[] dels = action.GetInvocationList();        foreach(var del in dels)        {             try             { ...执行委托   }              catch(..){}        //这里可以使用同步执行或者异步执行             //异步执行时,只有在调用EndInvoke方法后才会抛出异常。         }    }}

  

转载于:https://www.cnblogs.com/lztwj/p/5369687.html

你可能感兴趣的文章
Apache Spark源码走读之18 -- 使用Intellij idea调试Spark源码
查看>>
VMware 中如何打开U盘弹出U盘或者移动硬盘的(两种方法)
查看>>
南阳38--布线问题
查看>>
通过jsp请求Servlet来操作HBASE
查看>>
Learn Python 012: for loop
查看>>
安全试验资源
查看>>
系统问题
查看>>
StanFord ML 笔记 第六部分&&第七部分
查看>>
NFS服务搭建
查看>>
echarts雷达图点击事件 包含(2.x,3.85,4.02)测试
查看>>
spring boot 加载过程分析--ConfigurationClassPostProcessor
查看>>
[译] Fiber内幕:深入概述React新的协调算法
查看>>
app设计摘要
查看>>
Typescript 的成长环境
查看>>
转 C++STL之string
查看>>
demo06 webpack + babel7 + typescript
查看>>
eureka 服务实例实现快速下线快速感知快速刷新配置解析
查看>>
C# 给DateTime赋值正确方式
查看>>
html中子界面与父界面相互操作或传值
查看>>
转岗·空调工程师·自己动手拆空调记录
查看>>