Delegates 和Events的应用

来源:互联网 发布:淘宝投诉结果 编辑:程序博客网 时间:2024/05/18 03:59

 最近要对他进行二次开发.以前从来没有接触过,所以感觉很兴奋,因为又可以学到很多东西了。看了很多资料,今天归纳一下:
以异常出错为例进行阐述。他的调用过程是这样的:
1:在错误发生后,调用Application_OnError方法;
public class CSHttpModule : IHttpModule       {
 private void Application_OnError (Object source, EventArgs e)
        {.....................
             CSEvents.CSException(csException);          }
   }
每一个http请求都会调用这个模块的.注意此类中IHttpModule的定义.
2:在方法的最后调用CSEvents.CSException(csException)  // 调用CSEvents类中的CSException方法
public static void CSException(CSException csEx)
  {
   CSApplication.Instance().ExecuteCSExcetion(csEx);
  }
3:进入CSEvents包装器,调用CSApplication.Instance().ExecuteCSExcetion(csEx);
4:执行CSApplication.Instance()方法,等执行完后再执行ExecuteCSExcetion.如果是第一次执行就根据communityserver.config文件中的配置,把所有的CSModules实例化,并且调用ICSModule接口类中的Init方法,然后缓存这些实例化的类(如果是第二次访问就从缓存中读取)
communityserver.config
<CSModules>
<add name = "CSExceptionModule" type = "CommunityServer.Components.CSExceptionModule, CommunityServer.Components" />
</CSModules>
public class CSApplication
 {
internal static CSApplication Instance()
  {   .............
      XmlNode node = config.GetConfigSection("CommunityServer/CSModules");
       ..........
      CSCache.Max(key, app,dep);

  }
 }
public interface ICSModule
 {
  void Init(CSApplication csa, XmlNode node);
 }
public class CSExceptionModule : ICSModule
 {
   public void Init(CSApplication csa, System.Xml.XmlNode node)
  {
   csa.CSException +=new CSExceptionHandler(csa_CSException);
  }
}
5:在实现ICSModule接口的类中,CSExceptionModule.csInit方法是给事件添加委托的过程,这个过程中实现了委托指向的一个或者多个方法与事件进行关联,异常处理的方法csa_CSException(CSException csEx, CSEventArgs e)就是在这里被关联到异常事件上的。
6:经过上面几步后(前边已经提过,初始化完后,也就是创建了应用程序对象后,接着执行ExecuteCSExcetion)CS系统接着调用ExecuteCSExcetion方法,在ExecuteCSExcetion方触发了CSException事件
7CSException事件被触发后,就执行事件中委托所指向的函数,这里是CSExceptionModule.cs文件中的
public class CSExceptionModule : ICSModule
 {

   public void Init(CSApplication csa, System.Xml.XmlNode node)
  {
   csa.CSException +=new CSExceptionHandler(csa_CSException);
  }
  private void csa_CSException(CSException csEx, CSEventArgs e)
  {}
}
8:那么这个CSException又是怎么回事?在哪里定义的?我们回到CSApplication.cs文件中
 public event EventHandler PostConfigurationInitialized
        {
            add{Events.AddHandler(ConfigurationInitialized, value);}
            remove{Events.RemoveHandler(ConfigurationInitialized, value);}
        }

这里定义了一个CSException事件,而事件发生的时候只能用CSExceptionHandler这个委托来做跑腿的。其实CS中是把委托都存放在了一个EventHandlerList中,因此此处你可以看到addremove, 这是访问器的声明,用于添加或移除客户代码中的事件处理程序,这样做的好处是公开大量的事件但不为每个事件分配字段,而是使用EventHandlerList存储这些事件实例。为了理解事件的调用执行过程,我们还必须看几个文件:CSEvents.csCSEventArgs.cs
9:
CSEventArgs.cs存储事件的数据,这个很好理解,它继承自EventArgs。当事件发生时CSEventArgs用来传递事件的信息,这里传递两个值:ObjectStateApplicationType(可以在Enumerations文件夹下找到这两个枚举的内容)
CSEvents.cs这是对事件调用的一个包装器,看异常处理的包装:
public class CSApplication
internal void ExecuteCSExcetion(CSException csEx)

         
{

             CSExceptionHandler handler 
= Events[EventUnhandledException] as CSExceptionHandler;

            
if (handler != null)

              
{
                   handler(csEx,
new CSEventArgs());

              }


         }

大家看的是不是很乱呀!其实我分析了很长时间的.
总结一下 :
首先,请求页,遇到错误,调用CSHttpModule,触发事件CSEvents.CSException(csException),初始化applycationg(CSApplication.Instance().ExecuteCSExcetion(csEx)(在此类中,他告诉你:你只能通过谁来委托,并具有错误的能力ExecuteCSExcetion),初始化时有一个委托public delegate void CSExceptionHandler(CSException csEx, CSEventArgs e);会让你去读communityserver.config并把所有的CSModules实例化type = "CommunityServer.Components.CSExceptionModule,这时把事件委托给了方法.