我是否需要关闭和/或处理通过OperationContext.Current.GetCallbackChannel获取的回调通道?

时间:2011-11-17 10:13:05

标签: wcf callback dispose

我正在使用OperationContext.Current.GetCallbackChannel来获取调用WCF服务操作的客户端的通道。

我是否需要担心关闭/处理这些回调通道,还是由框架处理?

2 个答案:

答案 0 :(得分:6)

嗯,我只是自己尝试了,结果发现如果你关闭&处理回调通道(在转换为IClientChannel之后)整个服务通道变得无用,并且在被调用时抛出一个ProtocolException:

“由于服务器启动的关闭,输出会话自动关闭,因此该通道不能再用于发送消息。通过将DispatchRuntime.AutomaticInputSessionShutdown设置为false来禁用自动关闭,或者考虑修改关闭协议与远程服务器。“

我认为这是一个不受欢迎的后果或试图关闭& amp;处置回调通道,意味着不应该这样做。

答案 1 :(得分:1)

在我看来你应该。

回调机制不像高级协议那样提供管理 服务和回调端点之间的连接。这取决于开发人员 提出一些应用程序级协议或一致的模式来管理 连接的生命周期。如果客户端通道仍处于打开状态,则该服务只能回调客户端,这通常通过不关闭代理来实现。保持代理打开也会阻止回调对象被垃圾回收。如果服务在回调端点上维护引用并且客户端代理关闭或客户端应用程序本身消失,则当服务调用回调时,它将从服务通道获得ObjectDisposedException。因此,当客户不再希望接收回叫或客户端应用程序正在关闭时,最好通知服务。为此,您可以向服务合同添加显式Disconnect()方法。由于每个方法调用都带有回调引用,因此在Disconnect()方法中,服务可以从其内部存储中删除回调引用。

这是一个例子:

class MyService : IServiceContract
{
   static List<IServiceContractCallback> m_Callbacks = new List<IServiceContractCallback>();
public void Connect()
{
    IServiceContractCallbackcallback = OperationContext.Current.GetCallbackChannel<IServiceContractCallback>();
    if(m_Callbacks.Contains(callback) == false)
    {
       m_Callbacks.Add(callback);
    }
}
public void Disconnect()
{
    IServiceContractCallback callback = OperationContext.Current.GetCallbackChannel<IServiceContractCallback>();
    if(m_Callbacks.Contains(callback))
    {
        m_Callbacks.Remove(callback);
    }
    else
    {
        throw new InvalidOperationException("Cannot find callback");
    }
}

通过这种方式,客户端可以通知服务不再需要回调。它回答了你的问题吗?

相关问题