我设法通过回调功能获得我的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
}
答案 0 :(得分:1)
在您的情况下,您无需执行其他步骤。因为您的客户每个都获得自己的服务实例,所以当客户端通道关闭时,回调通道将超出范围。 (注意:这是因为服务实例模式是Per Session)
因此,您只需要从客户端调用客户端通道上的Close(),一切都将超出服务端的范围。不要忘记以正确的方式关闭频道:
try
{
channel.Close();
}
catch
{
channel.Abort();
throw;
}
要么超过或等待超过服务接收超时,那么会话将结束,并且通道将超出范围。但这有点浪费,因为服务将在服务器上的内存中保留更长时间。
注意,没有必要在服务端的回调通道上调用Close / Dispose。