zoukankan      html  css  js  c++  java
  • 类库探源——System.Delegate

    一、MSDN 描述

    Delegate 类:表示委托,委托是一种数据结构,它引用静态方法或引用类实例及该类的实例方法。(是不是感觉很像C语言中的函数指针 :) )

    命名空间: System

    程序集:   mscorlib.dll

    说到 Delegate 就必须谈 MulticastDelagate

    MulticastDelagate类 :表示多路广播委托;即,其调用列表中可以拥有多个元素的委托。

    命名空间: System

    程序集:   mscorlib.dll

    继承关系:

    备注:

    1. Delegate 类是委托类型的基类

    2. MulticastDelegate 继承自Delegate(这是废话,上面的继承关系那么明显)

    3. MulticastDelegate 拥有一个带有链接的委托列表,该列表称为调用列表(虚函数表 Virtual Method Table)

    4. 如果MulticastDelegate 的委托列表中某一个委托执行时发生异常,则在这个委托后面的委托不会执行

    5. C# 中 delegate 与 Delegate 和 MulticastDelagate 的关系:

    在C#中用 delegate 关键字标示一个方法 编译器将自动生成一个继承自 System.MulticastDelegate 的以方法名为类名的类,且添加 BeginInvoke 和 EndInvoke 方法

    using System;
    
    public delegate void CustomDelaget();    
    // 用 delegate 关键字 编译器将自动生成一个继承自 System.MulticastDelegate 的类
    /*
    .class public auto ansi sealed CustomDelaget
           extends [mscorlib]System.MulticastDelegate
    {
    } // end of class CustomDelaget
    */
    class App
    {
        static void Main()
        {
            CustomDelaget d = new CustomDelaget(Invoke);
            d.Invoke();
        }
        
        static void Invoke()
        {
        }
    }
    View Code

    二、用 Action 和 Func 代替自定义委托

    Action 表示没有返回值的委托

    Func 表示有返回值的委托

    话说Action 和 Func 程序集分得有点怪异,Func 和 Action 程序集一样,以 Action 为例

    Action(T) --> Action(T1,T2,T3,T4,T5,T6,T8) 的程序集为 mscorlib.dll

    Action(T1,T2,T3,T4,T5,T6,T8,T9) -->  Action(T1,T2,T3,...,T16) 的程序集为 System.Core.dll

    这给人最初设计折类库的人觉得最多8个参数就够了,后来发现8个参数又不够,又加了8个放在 System.Core.dll 下的感觉

    三、异步

    1. 基于委托的异步(传统异步)

     .NET Framework 运行你用传统异步的方式调用任何方法,只要你定义与你所需要调用的方法具有相同签名的委托,CLR会自动为该委托加上 BeginInvoke 和 EndInvoke

    BeginInvoke 方法启动异步调用。

    定义:
    IAsyncResult BeginInvoke(待异步执行方法的参数表,AsyncCallback 委托,object State)

    EndInvoke 方法检索异步调用的结果

     如委托有返回值

    var 委托的返回值 = EndInvoke(IAsyncResult ar);

    如果 委托没有返回值则为 

    EndInvoke(IAsyncResult ar);

    例子:

     1 using System;
     2 using System.Threading;
     3 using System.Runtime.Remoting.Messaging;
     4 
     5 // 无返回值的委托
     6 public delegate void StringHanlder(string msg);
     7 
     8 // 待返回值的委托
     9 public delegate string StringHanlderV2(string msg);
    10 class App
    11 {
    12     static void Main()
    13     {
    14         StringHanlder handler = new StringHanlder(PrintMsg);
    15         handler.BeginInvoke("待打印信息",new AsyncCallback(CallBack),string.Format("从{0}线程跳转而来",Thread.CurrentThread.ManagedThreadId));
    16         
    17         // 待返回值
    18         StringHanlderV2 handler2 = new StringHanlderV2(PrintMsgV2);
    19         handler2.BeginInvoke("待打印信息V2",new AsyncCallback(CallBackV2),string.Format("V2从{0}线程跳转而来",Thread.CurrentThread.ManagedThreadId));
    20         
    21         Thread.Sleep(1000*100);
    22     }
    23     
    24     static void PrintMsg(string msg)
    25     {
    26         Console.WriteLine(msg);
    27     }    
    28     
    29     static void CallBack(IAsyncResult ar)
    30     {
    31         AsyncResult result = (AsyncResult) ar;
    32         StringHanlder caller = (StringHanlder) result.AsyncDelegate;
    33         string formatString = (string) ar.AsyncState;
    34         caller.EndInvoke(ar);
    35         
    36         Console.WriteLine(result);
    37         Console.WriteLine(caller);
    38         Console.WriteLine(formatString);
    39     }
    40     
    41     
    42     static string PrintMsgV2(string msg)
    43     {
    44         Console.WriteLine(msg);
    45         return "已成功打印";
    46     }
    47     static void CallBackV2(IAsyncResult ar)
    48     {
    49         AsyncResult result = (AsyncResult) ar;
    50         StringHanlderV2 caller = (StringHanlderV2) result.AsyncDelegate;
    51         string formatString = (string) ar.AsyncState;
    52         var strRet = caller.EndInvoke(ar);
    53         
    54         Console.WriteLine(result);
    55         Console.WriteLine(caller);
    56         Console.WriteLine(formatString);
    57         Console.WriteLine(strRet);
    58     }
    59 }
    View Code

    结果:

    2. 基于事件的异步

    2014-12-29 补充

    委托的几种初始化方式(原始方式、方法、匿名方法、Lambda 方式)

    using System;
    
    public delegate void MyDelegate();
    class App
    {
        static void Main()
        {
            //MyDelegate d = new MyDelegate(Method1);    // 原始方式
            //MyDelegate d = Method1;                    // 方法形式
            //MyDelegate d = delegate{Console.WriteLine("Method1");}; // 匿名方法
            MyDelegate d = () =>Console.WriteLine("Method1");    // Lambda 表达式
            d.Invoke();
        }
        
        static void Method1()
        {
            Console.WriteLine("Method1");
        }
    }

    未完

  • 相关阅读:
    SpringMVC:com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax;
    SpringMVC DELETE,PUT请求报错 添加支持Http的DELETE、PUT请求
    HashMap源码总结
    ArrayList动态扩容大小
    Java中的可选操作
    Java中深拷贝与浅拷贝理解
    String在内存中如何存储
    异常处理—checked exception 和 unchecked exception
    Comparable和Comparator区别
    Scanner类与Readable接口
  • 原文地址:https://www.cnblogs.com/Aphasia/p/4155754.html
Copyright © 2011-2022 走看看