Reputation: 9397
This is what I understand from why we need to implement our own wrapper class for serviceClients (please correct me if I'm wrong):
The purpose of catching the exception in the Dispose() method is that .Close() may throw either a "CommunicationException" or "TimeoutException" - and to prevent the connection to hang you catch those two exceptions to use .Abort() which will change the state of the communication object to closed immediatley. - it would not make any sense to let the exception be unhandled because the nessecary calls to the methods have already been made since we're at the Dispose() part, and it would therefore be odd to throw an exception when the job actually is done as it should.
But why do:
public class ServiceClientWrapper<TServiceType> : IDisposable
{
public TServiceType Channel { get; private set; }
private readonly ChannelFactory<TServiceType> _channelFactory;
public ServiceClientWrapper(string endpoint)
{
_channelFactory = new ChannelFactory<TServiceType>(endpoint);
Channel = _channelFactory.CreateChannel();
((IChannel)Channel).Open();
}
#region Implementation of IDisposable
public void Dispose()
{
try
{
((IChannel)Channel).Close();
}
catch (CommunicationException ex)
{
((IChannel)Channel).Abort();
}
catch (TimeoutException ex)
{
((IChannel)Channel).Abort();
}
catch (Exception)
{
((IChannel)Channel).Abort();
throw;
}
}
#endregion
}
When you can do:
public class ServiceClientWrapper<TServiceType> : IDisposable
{
public TServiceType Channel { get; private set; }
private readonly ChannelFactory<TServiceType> _channelFactory;
public ServiceClientWrapper(string endpoint)
{
_channelFactory = new ChannelFactory<TServiceType>(endpoint);
Channel = _channelFactory.CreateChannel();
((IChannel)Channel).Open();
}
#region Implementation of IDisposable
public void Dispose()
{
((IChannel)Channel).Abort();
}
#endregion
}
According to MSDN both .Close()
and .Abort()
will change the state of the communication object to "Closed"?
Upvotes: 0
Views: 2795
Reputation: 12135
The point is that Close() will aim to close the entire communication channel gracefully, including any closing handshake required by the communication protocol, whereas Abort() is a rude and brutal tearing down of the client-side channel stack with no attempt to communicate the closure properly to the other side. Abort may therefore leave server-side resources still tied up on a connections which will not be used further.
So we always want to execute Close if possible, but we need to handle situations where things are so broken that trying to do a Close will cause a further exception.
Upvotes: 3
Reputation: 42494
Close method:
http://msdn.microsoft.com/en-us/library/ms405496.aspx
This method causes a CommunicationObject to gracefully transition from any state, other than the Closed state, into the Closed state. The Close method allows any unfinished work to be completed before returning. For example, finish sending any buffered messages.
Abort method Does the same ungracefully or as stated in the specs immediately. It will NOT finish anything still going on...
Upvotes: 2