C#委托
关于什么是委托,委托如何使用,我在这里就不说了。
需要说的:
委托是函数指针链
委托的 BeginInvoke
委托如果出现异常,会如何
如果不知道函数指针,可以继续往下看,我来告诉大家,为何需要委托。
假如在写游戏,有一个人物,他会升级,那么在他升级的时候,需要给他添加潜力值,而判断升级是经验类需要写的。
先写一个经验类。
核心
如果当前经验大于最大经验,升级。
但是升级是在经验类里,经验类外的人物不会知道已经升级了,那么如何让人物知道升级?
这时可以使用委托。
如果当前经验大于最大经验
调用函数升级
那么函数 升级 如何让人物知道,可以使用一个委托
升级
调用委托
于是人物可以添加函数到经验。
经验.升级=人物.升级
这样,经验的升级就是使用人物的升级,可以使用其他类的函数。
上面没有代码,现在来说个有代码的。
假如需要去寄快递,那么需要找邮递,把东西给他
假设有个邮递,可以寄快递
class 邮递
{
public static Action 寄快递;
}
委托最好用Action
这里定义委托是,不知道会是哪个快递员会去寄快递,在实际,谁也不知道最后是哪个,快递员可能说不想干了,实际快递太辛苦,大家多体谅。所以不能写函数说,快递A 给 小明去寄,因为不知道小明是不是今天上班。
来写一个 主角 张 ,他需要去寄快递。
class MrZhang
{
public void 寄快递()
{
邮递.寄快递();
}
}
不知道是谁上班,但是我可以寄快递。
最后,今天来上班的快递员
快递员 a = new 快递员();
邮递.寄快递 = a.寄快递;
class 快递员
{
public void 寄快递()
{
}
}
就是快递,所以这就是委托使用。
使用一个函数,不知道他是谁用的,可以使用委托。
如果使用的委托是 多播,那么小心用 BeginInvoke
如果使用 同步,那么多个方法是可以运行
static void Main(string[] args)
{
Action m = M1;
m += M2;
m.Invoke();
}
private static void M1()
{
p();
}
private static void M2()
{
p();
}
private static void p()
{
Console.WriteLine("线程ID为:{0}", Thread.CurrentThread.ManagedThreadId);
}
如果使用的BeginInvoke,那么在委托多播使用 BeginInvoke 会报异常 System.ArgumentException:“The delegate must have only one target.”
在一个线程不能同时执行多个方法,使用 BeginInvoke 必须在多个线程,所以可以使用 获得所有方法,然后执行
static void Main(string[] args)
{
Action m = M1;
m += M2;
//m.Invoke();
List<IAsyncResult> list=new List<IAsyncResult>();
var invtl = m.GetInvocationList().OfType<Action>().ToList();
foreach (Action temp in invtl)
{
list.Add(temp.BeginInvoke((e) => { }, null));
}
for (int i = 0; i < invtl.Count(); i++)
{
invtl[i].EndInvoke(list[i]);
}
}
private static void M1()
{
p();
}
private static void M2()
{
p();
}
private static void p()
{
Console.WriteLine("线程ID为:{0}", Thread.CurrentThread.ManagedThreadId);
}
有两个需要知道:
m.GetInvocationList() 得到 Delegate 不能直接执行。
需要转类型,定义是知道他是什么类型,上面使用的是 Action ,所以可以转 Action ,如果是自定义的,那么使用自定义的。
第二,如果使用 BeginInvoke ,在等待时,需要拿到 IAsyncResult 才可以。
var temp = m.BeginInvoke((e) => { }, null);
m.EndInvoke(temp);
上面代码:如果要使用 BeginInvoke ,小心 Delegate 是多个函数,不是一个函数,所以使用时,建议使用
var invtl = m.GetInvocationList().OfType<Action>().ToList();
foreach (Action temp in invtl)
{
list.Add(temp.BeginInvoke((e) => { }, null));
}
需要把类型换自己的类型。
如果委托发生异常
如果委托方法里没有 try catch,那么如果使用 invoke, 委托是函数指针链,所以会在执行异常退出。
如果使用 BeginInvoke ,那么会在 EndInvoke 退出。
static void Main(string[] args)
{
Action m = M1;
m += M2;
//m.Invoke();
List<IAsyncResult> list=new List<IAsyncResult>();
var invtl = m.GetInvocationList().OfType<Action>().ToList();
foreach (Action temp in invtl)
{
list.Add(temp.BeginInvoke((e) => { }, null));
}
//for (int i = 0; i < invtl.Count(); i++)
//{
// invtl[i].EndInvoke(list[i]);
//}
}
private static void M1()
{
p();
throw new ArgumentException();
}
private static void M2()
{
p();
throw new ArgumentException();
}
private static void p()
{
Console.WriteLine("线程ID为:{0}", Thread.CurrentThread.ManagedThreadId);
}
上面代码没有 EndInvoke 不会有异常,异常发生在别线程,所以不会在Main函数异常。
如果使用 EndInvoke 会在 Main 异常
static void Main(string[] args)
{
Action m = M1;
m += M2;
//m.Invoke();
List<IAsyncResult> list=new List<IAsyncResult>();
var invtl = m.GetInvocationList().OfType<Action>().ToList();
foreach (Action temp in invtl)
{
list.Add(temp.BeginInvoke((e) => { }, null));
}
for (int i = 0; i < invtl.Count(); i++)
{
invtl[i].EndInvoke(list[i]);
}
}
private static void M1()
{
p();
throw new ArgumentException();
}
private static void M2()
{
p();
throw new ArgumentException();
}
private static void p()
{
Console.WriteLine("线程ID为:{0}", Thread.CurrentThread.ManagedThreadId);
}
事件
如果事件使用 BeginInvoke 和 委托一样
_event += (s, e) => M1();
_event += (s, e) => M2();
_event?.BeginInvoke(null, null, (e) => { }, null);
private static EventHandler _event;
异常:System.ArgumentException:“The delegate must have only one target.”
需要和 委托 一样,获得函数指针,执行,如果方法里有异常,那么不会在 Main 方法异常,如果没有使用 End 。
foreach (var temp in _event.GetInvocationList().OfType<EventHandler>())
{
temp.BeginInvoke(null, null, (e) => { }, null);
}
本文还没写好,如果有问题,请联系我
本文内容属于大量抄袭,代码是自己写,但是抄了代码大神写的,于是羞愧放下他的博客:
http://www.cnblogs.com/free722/archive/2011/04/04/2005275.html
http://stackoverflow.com/questions/25979264/understanding-the-wpf-dispatcher-begininvoke
本文会经常更新,请到原文:http://lindexi.oschina.io/lindexi//post/C-%E5%A7%94%E6%89%98

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
C#委托的更多相关文章
- HTML 事件(三) 事件流与事件委托
本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...
- C#基础篇 - 理解委托和事件
1.委托 委托类似于C++中的函数指针(一个指向内存位置的指针).委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针.简单理解,委托是一种可以把函数当做参数传递的类型.很多情况下,某 ...
- [.NET] C# 知识回顾 - 委托 delegate (续)
C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...
- [C#] C# 知识回顾 - 委托 delegate
C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...
- 9、委托、事件、Lambda
开始 关于委托,肯定是要有问题的. 第一个问题,委托用来干什么? 看.net中的表述:在.net平台下,委托类型用来定义和相应应用程序中的回调.(回调?处理内存中两个实体双向通信的一种技术.) 第 ...
- iOS 委托与文本输入(内容根据iOS编程编写)
文本框(UITextField) 本章节继续编辑 JXHypnoNerd .文件地址 . 首先我们继续编辑 JXHypnosisViewController.m 修改 loadView 方法,向 ...
- C#委托异步调用
参考页面: http://www.yuanjiaocheng.net/webapi/mvc-consume-webapi-get.html http://www.yuanjiaocheng.net/w ...
- JavaScript事件代理和委托(Delegation)
JavaScript事件代理 首先介绍一下JavaScript的事件代理.事件代理在JS世界中一个非常有用也很有趣的功能.当我们需要对很多元素添加事件的时候,可以通过将事件添加到它们的父节点而将事件委 ...
- .NET面试题系列[7] - 委托与事件
委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...
- .NET基础拾遗(4)委托、事件、反射与特性
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
随机推荐
- 团队作业9——Beta版本展示博客
一. 骆杰宁(组长) 风格:少说话,多做事. 擅长技术:Jsp 编程兴趣:GUI 希望角色:PM 一句话宣言:年轻是本钱,不努力就不值钱. 胡丹丹 风格:不断沉淀自己 擅长技术:擅长TCP/IP协议模 ...
- 【Beta】 第二次Daily Scrum Meeting
一.本次会议为第二次meeting会议 二.时间:13:30AM-13:55AM 地点:禹州 三.会议站立式照片 四.今日任务安排 成员 昨日任务 今日任务 林晓芳 对已完成的功能进行进一步测试,以便 ...
- 201521123103 《Java学习笔记》 第六周学习总结
一.本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 二.书面作业 1.clone方法 1.1 Object对象中 ...
- 201521123031《java程序设计》第五周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过?哪句 ...
- 201521123089 《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码1.1 com.parent包中Child.java文件能否编译通过?哪 ...
- 201521123032 《Java程序设计》第2周学习总结
1. 本周学习总结 本周java回顾了各种数据类型,在java中使用浮点型会不精确,改用double行就好.学习了string的类型,string的对象是不可变的,创建之后不能再修改,在string的 ...
- 【SQL】- 基础知识梳理(三) - SQL连接查询
一.引言 有时为了得到一张报表的完整数据,需要从两个或更多的表中获取结果,这时就用到了"连接查询". 二.连接查询 连接查询的定义: 数据库中的表通过键将彼此联系起来,从而获取这些 ...
- [js学习笔记] 原型链理解
js中只有对象,包括对象,函数,常量等. prototype 只有函数里有这个属性. 对象里可以设置这个属性,但是没这个属性的意义 prototype指向一个对象,可以添加想要的方法. 该对象里有一个 ...
- Storm同步调用之DRPC模型探讨
摘要:Storm的编程模型是一个有向无环图,决定了storm的spout接收到外部系统的请求后,spout并不能得到bolt的处理结果并将结果返回给外部请求.所以也就决定了storm无法提供对外部系统 ...
- const的用法,特别是用在函数前面与后面的区别!
const的用法,特别是用在函数后面 在普通的非 const成员函数中,this的类型是一个指向类类型的 const指针.可以改变this所指向的值,但不能改变 this所保存的地址. 在 const ...