通道状态机
通道和通道工厂拥有相同的特性,这些特性独立于运行时功能。其中最重要 的特性之一就是他们拥有公共的状态机。WCF程序里的每个通道和通道工厂都有 一个预定义的状态集合和一个预定义的方法集合,这些方法会控制通道和通道工 厂在这些状态之间转换。
ICommunicationObject接口
在面向对象层次上,WCF类型系统强制实现了各个通道共用一个状态机,方式 就是就是所有的通道和通道工厂都实现 System.ServiceModel.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; }
}
备注:本节里为了简洁起见,这里我只会把实现ICommunicationObject接口 的类型作为通道,尽管通道工厂也实现了这个接口。
我们先看一下方法。为了打开、关闭和终止通道,ICommunicationObject声 明了几个方法。这里重载了几个接受TimeSpan参数的异步Open和Close方法。理 论上,无参的Open和Close方法会阻塞,直到通道最终打开或者关闭。实际上, 这样不好,重载的方法带有一个TimeSpan参数,它表示愿意等待的通道对象打开 或者关闭的时间。因为调用者不应该无限期等待通道打开或者关闭,所以无参的 Open和Close方法应该传递一个默认TimeSpan值去调用重载后的方法。
ICommunicationObject接口还定义了符合微软异步编程模型的BeginOpen和 BeginClose方法。因为打开和关闭一个通道可能要涉及到I/O,因此使用异步编 程模型是个不错的方法。这样做意味着程序可以在打开和关闭通道的时候,使用 线程池来实现资源的高效管理和线程调用,而不需要阻塞进程。这里重载了允许 传递TimeSpan参数的BeginOpen和BeginClose方法来,和其它的方法很像,但是 不同的是这些方法可以设置等待的时间。在打开和关闭通道的时候,我推荐使用 ICommunicationObject接口里定义的异步方法。
ICommunicationObject接口也定义了一个CommunicationState 类型的只读属 性。这个成员是为了查询通道目前的状态。你会在下一节 “CommunicationObject类型”里学习更多的通道状态机的内容。现在,我们来 看一下CommunicationState状态值,如下所示,是个枚举类型:
public enum CommunicationState {
Created,
Opening,
Opened,
Closing,
losed,
Faulted
}
ICommunicationObject接口也定义了几个事件。如其它的.NET Framework事 件一样,这些事件是其它对象接受通道状态改变通知的一种方法。事件的名字与 状态类型CommunicationState相关。我们会在下一节详细学习这些事件。