WCF代理运行时初始化和性能含义

时间:2011-09-27 04:54:40

标签: wcf wcf-client

我正在通过ChannelFactory类手动初始化我的代理,因为初始化此代理的配置来自其他一些配置服务(不在同一个App.Config中)并且为了避免初始化成本(服务调用,读取配置设置)我缓存了这个代理。我无法承担每次操作后关闭此代理的成本,因为需要频繁执行操作。此代理的超时配置如下。

receiveTimeout="00:10:00" 
sendTimeout="00:10:00" 
closeTimeout="00:10:00"

根据我对客户端Timeout属性的理解,当超时超过时,我的代理状态将为Fault。对?

我想重新初始化我的代理,所以我有2个选项来执行此操作。

1)我使用ICommunicationObject.Faulted事件处理程序,当我的代理进入故障状态时,即使我重新初始化代理。但是这种实现并不合适,因为我们没有正确处理代理(调用.Close()方法),它不会从服务端释放资源并影响我的性能。

2)我创建一个Thread并设置它在代理进入Faulted状态前几秒的经过时间。通过调用.Close {)方法正确关闭此代理并重新初始化另一个对象并对其进行缓存。

请建议我哪个选项在性能方面表现良好,如果存在其他解决方案以避免此问题,请告诉我。

提前致谢。

1 个答案:

答案 0 :(得分:0)

如果代理处于故障状态,您可以在其上调用Abort。 如果你真的想保持代理,取决于你需要什么。如果您打算使用Duplex-Communication或类似的东西可能是一个很好的建议。如果您不时只拨打服务,则只能在通话期间使用代理。

我正式去写一个只发布Connected和Fault事件的小代理。我使用首先尝试关闭代理的代码实现IDisposable,并在抛出CommunicationException时继续中止它。

在处理通信的代码中,我持有对这样一个代理对象的引用并将其处理为Close / Fault,并在我有一个挂起的操作时立即打开它。 即使网络不可靠,这在客户端也能很好地工作。 如果是Duplex-Services,我只需添加一个计时器,如果连接丢失,它会尝试自动重新连接。

这是F#中的一个小片段,展示了我使用这个非常简单的代理的方式 - 它实际上只不过是包装Channel并获取连接事件 - WcfHelper只是一堆辅助函数来构建地址和绑定 - 这种情况是DuplexService的精简版本,因此它继承自DuplexClientBase,但普通非双工案例是相同的。

/// Duplex-proxy
type private MyProxy(handler, servicename: string, server : string, port : int) =
    inherit DuplexClientBase<IWcfConnector>(handler, WcfHelper.getBinding(), WcfHelper.createEndpointAddress(servicename, server, port))

    let _connectionEvent = new Event<_>()

    do
        base.InnerDuplexChannel.Closed.Add(fun _ -> _connectionEvent.Trigger(ConnectionState.Disconnected))
        base.InnerDuplexChannel.Opened.Add(fun _ -> _connectionEvent.Trigger(ConnectionState.Connected))
        base.InnerDuplexChannel.Faulted.Add(fun _ -> _connectionEvent.Trigger(ConnectionState.Disconnected))

    /// sample-Operation
    member i.TestCall(message) = base.Channel.TestCall(message)

    interface IDisposable with
        member i.Dispose() =
            try
                i.Close()
            with
            | :? CommunicationException ->
                i.Abort()