Item 21:通过委托实现回调

  通过委托实现回调,那么什么是回调呢,作者在书中给了一个解释:回调是用来提供从服务器到客户端的异步信息反馈。

我的理解是客户端向服务器端提出一个请求,然后服务器端开始执行该请求,而客户端继续做自己的工作。当服务器端执行完请求时,或发生一些状态改变时,就可

以向客户端反馈信息。在c#中是通过委托来实现回调的,委托是一个包含对方法引用的对象,该方法可以是静态的,也可以是实例方法。

  c#中的委托是一个类型安全的回调定义,比如在c#中定义一个委托:

 

public class UseDelegate
{
    
public delegate bool ContinueProcessing(int parm);
}  

 

 

上面定义的委托是类型安全的,该定义要求该委托包含的方法签名中传入一个整型参数,返回一个bool值,所以委托相当于一个类型安全的函数指针。

c#中使用委托最多的便是事件,但不是只有在定义事件时,才使用委托,任何你需要在运行时决定你所调用的方法的时候都可以使用委托。当然,委托

的作用和目的便是能在运行时决定调用的方法。例如:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Delegate
{
    
class Program
    {
        
static void Main(string[] args)
        {
            ContinueProcessing cp 
= UseDelegate.Process;
            cp(
"Call this method");
        }
    }

    
public delegate void  ContinueProcessing(string output);
   
    
public class UseDelegate
    {
        
public static void Process(string output)
        {
            Console.WriteLine(output);
        }
    }
}

 

上述代码的输出为“Call this method”,上例是在运行时将UseDeletgate类的process方法赋给ContinueProcessing委托的,也就是说cp("Call this method")

是在运行时才知道要调用Process方法,而在编译时并不知道要调用哪个方法。对比下面代码:

 

class Program
    {
        
static void Main(string[] args)
        {
            UseDelegate.Process();
        }
    }

    
public class UseDelegate
    {
        
public static void Process(string output)
        {
            Console.WriteLine(output);
        }
    }

 

 

这个例子就是在编译时就已经决定在Main()函数里调用UseDelegate类的Prodess方法了。

接下来说一下多重委托,就是一个委托可以连接多个方法,形成一个委托链,还是举个例子吧:

 

class Program
    {
        
static void Main(string[] args)
        {
            Computer cp 
= UseDelegate.Addition;
            UseDelegate ud 
= new UseDelegate();
            cp 
+= ud.Multiplication;
            
int result = cp(23);
            Console.WriteLine(result.ToString());
//结果为“6”
        }
    }

    
public delegate int Computer(int a,int b);
   
    
public class UseDelegate
    {
        
public static int Addition(int a, int b)
        {
            
return (a + b);
        }

        
public int Multiplication(int a, int b)
        {
            
return a * b;
        }
    }

 

在上例的Main()函数中声明并初始化了一个委托cp,然后通过“cp += ud.Multiplication; ”将另一个类型安全的实例方法Multiplication链接到了

上一个委托方法的后面,形成委托链。但是,从上面的例子中我们可以看出存在两个问题:

一.多重委托的调用是按连接到委托对象上的顺序调用的,如果前面调用的方法抛出异常,那么后面的方法将可能不会被调用,可能导致安全性问题。

二.从上例的执行结果很容易看出多重委托调用的返回值是最后一个方法的返回结果,中间方法的结果将被忽略。

 

总结:.NET中的委托为在运行时实现回调提供了一种很好的机制,可以在运行时决定回调的目标,可以支持多个客户端(即使用多重委托),所以客户

   端的回调应该由.NET委托来实现。

posted @ 2009-09-10 11:23  PeterLau  阅读(281)  评论(0)    收藏  举报