如何取消订阅WCF服务

本文关键字:WCF 服务 取消 何取消 | 更新日期: 2023-09-27 18:10:21

我已经设法让我的WCF服务与回调工作。客户端只需"订阅"服务,服务就会启动一个计时器。这个定时器决定何时调用回调函数。

现在我的问题是如何退订客户因为简单地关闭客户端造成CommunicationException

禁用定时器的Unsubscribe()的实现是正确的还是应该执行其他步骤?

这是我的服务类:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.PerSession)]
internal class HostFunctions : IHostFunctions
{
    private static ILog _log = LogManager.GetLogger(typeof(HostFunctions));
    private IHostFunctionsCallback _callback;
    private Timer _timer;
    #region Implementation of IHostFunctions
    public void Subscribe()
    {
        _callback = OperationContext.Current.GetCallbackChannel<IHostFunctionsCallback>();
        _timer = new Timer(1000);
        _timer.Elapsed += OnTimerElapsed;
        _timer.Enabled = true;
    }
    public void Unsubscribe()
    {
        _timer.Enabled = false;
    }
    private void OnTimerElapsed(object sender, ElapsedEventArgs e)
    {
        if (_callback == null) return;
        try
        {
            _callback.OnCallback();
        }
        catch (CommunicationException comEx)
        {
            // Log: Client was closed or has crashed
            _timer.Enabled = false;
        }
    }
    #endregion
}

如何取消订阅WCF服务

在您的情况下,您不需要执行额外的步骤。因为每个客户端都有自己的服务实例,所以当客户端通道关闭时,回调通道将超出作用域。(注意:之所以会出现这种情况,是因为服务实例模式是Per Session)

因此,您只需要从客户端调用客户端通道上的Close(),所有内容都将超出服务端的作用域。不要忘记以正确的方式关闭通道:

try
{
    channel.Close();
}
catch
{
    channel.Abort();
    throw;
}

或者等待超过服务接收超时,然后会话将结束,通道将超出范围。但是,这有点浪费,因为服务将在服务器的内存中保留更长时间。

注意,没有必要从服务端在回调通道上调用Close/Dispose。