简体   繁体   English

不寻常的WCF客户端行为

[英]Unusual WCF Client behaviour

I have an SOA application that uses a duplex WCF service hosted within a Windows Service. 我有一个SOA应用程序,它使用Windows服务中托管的双工WCF服务。 The client itself is a WPF application. 客户端本身是WPF应用程序。

I'm seeing unusual behaviour on closing and restarting the client application. 我在关闭和重新启动客户端应用程序时看到异常行为。 If I start a new instance after closing one, nothing visibly appears to happen. 如果我在关闭一个实例后开始一个新实例,那么看起来就不会发生任何事情。 However, checking task manager shows the new instance is running as a background process. 但是,检查任务管理器会显示新实例正在作为后台进程运行。 If I try to start another new instance of the client application, it will display the error screen I've written - stating an error with the service. 如果我尝试启动客户端应用程序的另一个新实例,它将显示我写的错误屏幕 - 说明服务的错误。 Investigation has shown that the client cannot create a new instance of the service callback channel because another application has already registered the URL. 调查显示客户端无法创建服务回调通道的新实例,因为另一个应用程序已经注册了URL。 This is a System.ServiceModel.AddressAlreadyInUseException. 这是一个System.ServiceModel.AddressAlreadyInUseException。

If I then end the background client task in task manager, my client displaying the error message is then able to connect to the service and run as normal. 如果我然后在任务管理器中结束后台客户端任务,则显示错误消息的客户端可以连接到服务并正常运行。 I have also noticed that if I close the background task before starting a new instance, the new instance will also not appear. 我还注意到,如果在启动新实例之前关闭后台任务,则新实例也不会出现。

My concern here is that this is not useable and feels like a real hassle for users. 我担心的是,这是不可用的,对用户来说感觉真的很麻烦。 What could be going wrong? 怎么可能出错? It seems as if something is not cleaning up unmanaged resource but I've used ANTS and can't identify it. 似乎有些事情没有清理非托管资源但是我使用了ANTS并且无法识别它。 The client is created as: 客户端创建为:

IServiceCallback callback = new Callback();
_context = new InstanceContext(callback);

_channelFactory = new DuplexChannelFactory<IMyService>(_context, binding, endpoint);

_proxy =
    _channelFactory.CreateChannel();
((ICommunicationObject)_proxy).Open(TimeSpan.FromSeconds(5));

The Service's constructor uses the following code: Service的构造函数使用以下代码:

_callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();

var commObject = _callback as ICommunicationObject;
if (commObject != null)
{
    commObject.Faulted += ChannelFaulted;
    commObject.Closing += ChannelClosing;
    commObject.Closed += ChannelClosed;
}

OperationContext.Current.Channel.Faulted += ChannelFaulted;
OperationContext.Current.Channel.Closed += ChannelFaulted;

Before closing, the client calls the service's Disconnect method, which does: 在关闭之前,客户端调用服务的Disconnect方法,该方法执行以下操作:

var commObject = _callback as ICommunicationObject;
if (commObject != null)
{
    commObject.Faulted -= ChannelFaulted;
    commObject.Closing -= ChannelClosing;
    commObject.Closed -= ChannelClosed;
}

OperationContext.Current.Channel.Faulted -= ChannelFaulted;
OperationContext.Current.Channel.Closed -= ChannelFaulted;

Finally, the client closes the channels like this: 最后,客户端关闭这样的渠道:

foreach (var incomingChannel in _context.IncomingChannels.ToArray())
{
    incomingChannel.Close();
}
try
{
    var proxy = _proxy as IChannel;
    if (proxy != null)
    {
        proxy.Close();
    }
}
catch (Exception)
{
    _channelFactory.Abort();
}

Why am I seeing this unusual behaviour? 为什么我会看到这种不寻常的行为? Is there something I'm missing to close the channel or something I'm doing wrong to create it? 是否有一些我缺少关闭频道或我做错了什么来创建它? Or is it likely that there must be an issue elsewhere in my code that keeps the channel or session alive? 或者是否可能在我的代码中的其他地方存在一个问题,使通道或会话保持活动状态?

**UPDATE: ** I have been trying a few things and found out that if I start a client instance, close it, then leave it for an hour, I can start another instance with no issue. **更新:**我一直在尝试一些事情,并发现如果我启动一个客户端实例,关闭它,然后离开它一个小时,我可以启动另一个实例没有问题。 I've also discovered that if I restart the Windows Service after creating and closing an instance of the client application then I'm also able to create another in those circumstances. 我还发现如果在创建和关闭客户端应用程序的实例后重新启动Windows服务,那么我也可以在这些情况下创建另一个。

**UPDATE 2: ** Stepping through, I can see that the incomingChannel.Close() does not complete and does not throw an error. **更新2:**单步执行,我可以看到incomingChannel.Close()没有完成,也没有抛出错误。 I've removed that section and also find proxy.Close() does not complete and does not throw an exception. 我删除了该部分,也发现proxy.Close()没有完成,也没有抛出异常。 I've tried using the overloads and added a timeout, but no timeout exception is being thrown. 我尝试使用重载并添加了超时,但没有抛出超时异常。 The Service's Dispose() method is not hit at all. Service的Dispose()方法根本没有被击中。

Try closing your channel factory too. 尝试关闭您的频道工厂。

proxy.ChannelFactory.Close();
proxy.Close();

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

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