I have a SOA application that uses the WCF duplex service hosted on a Windows service. The client itself is a WPF application.
I see unusual behavior when closing and restarting the client application. If I start a new instance after closing it, nothing visible will happen. However, checking the task manager shows that the new instance is working as a background process. If I try to start a new instance of the client application, it will display the error screen that I wrote - reporting an error in the service. The study showed that the client cannot create a new instance of the service callback channel because another application has already registered the URL. This is a System.ServiceModel.AddressAlreadyInUseException.
If you then finish the background client task in the task manager, my client, which displays an error message, will be able to connect to the service and work as usual. I also noticed that if I close the background task before starting a new instance, the new instance will not appear either.
My concern is that this is not applicable and seems like a real problem for users. What could go wrong? Something does not seem to clear the unmanaged resource, but I used ANTS and cannot identify it. 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 constructor uses the following code:
_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 Disconnect method of the service, which performs the following actions:
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 as follows:
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 behavior? Is there something Iām missing to close the channel or something Iām doing wrong to create it? Or maybe there should be a problem in my code that supports a channel or session?
** UPDATE: ** I tried several things and found out that if I started the client instance, close it and then leave it for an hour, I can start another instance without problems. I also found that if I restart the Windows service after creating and closing the client application instance, then I can also create another one in these circumstances.
** UPDATE 2: ** After going through, I see that incoming_Channel.Close () does not complete and does not throw an error. I deleted this section and also found proxy.Close () did not complete and did not throw an exception. I tried using overloads and added a timeout, but a timeout exception is not thrown. The Dispose () method is not deleted.