在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等类似方法都是相同的流程;