• WCF基础:绑定(二)


    在WCF的绑定体系中,经常会碰到ICommunicationObject接口,无论是IChannel接口还是IChannelListener/IChannelFactory接口都继承了ICommunicationObject接口;可见ICommunicationObject接口在Bing体系中作用很重要;

    ICommunicationObject

     ICommunicationObject接口是通信对象状态装换的接口;

        public interface ICommunicationObject
        {
            event EventHandler Closed;
            event EventHandler Closing;
            event EventHandler Faulted;
            event EventHandler Opened;
            event EventHandler Opening;
            void Abort();
          
            IAsyncResult BeginClose(AsyncCallback callback, object state);
            IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state);
            IAsyncResult BeginOpen(AsyncCallback callback, object state);
            IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
            void Close();
            void Close(TimeSpan timeout);
            void EndClose(IAsyncResult result);
            void EndOpen(IAsyncResult result);
            void Open();
            void Open(TimeSpan timeout);
            CommunicationState State {  get; }
        }

       public enum CommunicationState
       {
        Closed = 4,
        Closing = 3,
        Created = 0,
        Faulted = 5,
        Opened = 2,
        Opening = 1
       }

     ICommunicationObject接口中的CommunicationState 枚举代表了通信对象的五种状态,而且在ICommunicationObject接口中提供了5个事件来对应通信对象的状态装换;比如在Open()方法中首先调用Opening事件,在方法结束之前调用Opened 事件;

    CommunicationObject

     在WCF中抽象类CommunicationObject继承了 ICommunicationObject接口,CommunicationObject类的目的是  为系统中所有面向通信的对象(包括通道、侦听器以及通道和侦听器工厂)公用的基本状态机提供通用的基实现。在抽象类中定义了一些通信对象在进行状态转换中的处理方法,通过这些抽象方法可以扩展相关的实现,比如ICommunicationObject接口的方法;

    public abstract class CommunicationObject : ICommunicationObject
    {
         public void Open()
         {
           this.Open(this.DefaultOpenTimeout);
         }
    
         public void Open(TimeSpan timeout)
         {
               using (ServiceModelActivity activity = (DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose) ? ServiceModelActivity.CreateBoundedActivity() : null)
           {
               if (DiagnosticUtility.ShouldUseActivity)
               {
                  ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
               }
               lock (this.ThisLock)
               {
                  this.ThrowIfDisposedOrImmutable();
                  this.state = CommunicationState.Opening;
                }
                bool flag = true;
                try
                {
                   System.Runtime.TimeoutHelper helper = new System.Runtime.TimeoutHelper(timeout);
                   this.OnOpening();
                   if (!this.onOpeningCalled)
                    {
                        throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpening"), Guid.Empty, this);
                    }
                    this.OnOpen(helper.RemainingTime());
                    this.OnOpened();
                    if (!this.onOpenedCalled)
                    {
                        throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpened"), Guid.Empty, this);
                    }
                    flag = false;
                    }
                    finally
                    {
                     if (flag)
                     {
                        if (DiagnosticUtility.ShouldTraceWarning)
                        {
                            TraceUtility.TraceEvent(TraceEventType.Warning, 0x80005, System.ServiceModel.SR.GetString("TraceCodeCommunicationObjectOpenFailed", new object[] { this.GetCommunicationObjectType().ToString() }), this);
                         }
                       this.Fault();
                      }
                   }
                }
            }
       protected abstract void OnOpen(TimeSpan timeout);
    }

    在CommunicationObject类执行Open方法,参数TimeSpan timeout为方法调用超时的时间;

    1.通过 this.state = CommunicationState.Opening 将通信对象的状态设置为正在打开的状态;

    2.调用  this.OnOpening()方法其实方法的内部就是调用ICommunicationObject接口的 EventHandler Opening 事件处理函数;

    3.然后执行 this.OnOpen(helper.RemainingTime())方法这个方法时抽象方法,需要在子类中进行扩展这个方法;

    4.当1.2.3都执行完毕后,这说明通信对象已经打开,然后调用this.OnOpened()方法,在这个方法执行EventHandler Opened事件处理函数,并将通信对象的状态设置为Opened状态;

    5.如果1.2.3.4的过程中有报错,则会将通信对象的状态设置为Fault状态;

    对于CommunicationObject类中其他的状态变更比如Close,Abort等类似方法都是相同的流程;

  • 相关阅读:
    C# 获取指定目录下所有文件信息、移动目录、拷贝目录
    土地利用数据库地图自动缩编软件--地图缩编
    全国不动产登记交流
    [记录]好用的文件上传插件webuploader
    Petapoco Update在使用匿名对象修改时提示“给定关键字不在字典中”
    解决在MySQL使用PetaPoco T4生成数据的实体时得到当前MySQL数据库下所有表的错误方法
    [知识积累]MySQL外键约束条件
    Js判断QQ在线状态不准确的解决办法
    稍带迷茫的秋日小记
    假如你有个idea,你将怎么去实现它?
  • 原文地址:https://www.cnblogs.com/h20064528/p/5176334.html
Copyright © 2020-2023  润新知