简体   繁体   English

如何退订WCF服务

[英]How to unsubscribe from WCF service

I've managed to get my WCF service with callbacks working. 我设法使WCF服务与回调一起工作。 The client simply "subscribes" to the service and the service starts a timer. 客户端只需“订阅”该服务,该服务就会启动计时器。 This timer determines when to call the callback function(s). 该计时器确定何时调用回调函数。

Now my question is how to unsubscribe the client because simply closing the client causes an CommunicationException . 现在我的问题是如何取消订阅客户端,因为仅关闭客户端会导致CommunicationException

Is my implementation of Unsubscribe() with disabling the timer correct or should I perform additional steps? 我在禁用计时器的情况下实现的Unsubscribe()是否正确,还是应该执行其他步骤?

Here's my service class: 这是我的服务班级:

[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
}

In your case, you don't need to perform additional steps. 就您而言,您无需执行其他步骤。 Because your clients each get their own service instance the callback channel will go out of scope when the client channel closes. 因为您的客户端各自都有自己的服务实例,所以当客户端通道关闭时,回调通道将超出范围。 (Note: this is the case because the service instance mode is Per Session) (注意:之所以如此,是因为服务实例模式是“每会话”)

So you only need to call Close() on the client channel from the client and everything will go out of scope on the service end. 因此,您只需要从客户端在客户端通道上调用Close(),一切就会超出服务端的范围。 Don't forget to close the channel in the correct way: 不要忘记以正确的方式关闭频道:

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

Either that or wait for the service receive timeout to be exceeded and then the session will end and the channel will go out of scope. 要么等待,要么等待该服务的接收超时被超过,然后会话将结束并且通道将超出范围。 This is slightly wasteful however as the service will remain in memory on the server for longer. 但是,这有点浪费,因为该服务将在服务器的内存中保留更长时间。

Note, it is not necessary to call Close/Dispose on the callback channel from the service end. 注意,不必从服务端在回调通道上调用Close / Dispose。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM