Skip to content

Instantly share code, notes, and snippets.

@romeshniriella
Last active August 29, 2015 14:00
Show Gist options
  • Save romeshniriella/11278527 to your computer and use it in GitHub Desktop.
Save romeshniriella/11278527 to your computer and use it in GitHub Desktop.
How to properly close and dispose using an extension method.
//http://www.niedermann.dk/2009/06/18/BestPracticeDisposePatternC.aspx
public class BestPracticeDisposePattern : IDisposable
{
private bool m_IsDisposed;
~BestPracticeDisposePattern()
{
Dispose(false);
}
[MethodImpl(MethodImplOptions.Synchronized)]
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool isDisposing)
{
if (m_IsDisposed)
return;
if (isDisposing)
{
FreeManagedRessources();
}
FreeUnmanagedRessources();
m_IsDisposed = true;
}
protected virtual void FreeManagedRessources()
{
//Free managed ressources here. Typically by calling Dispose on them
}
protected virtual void FreeUnmanagedRessources()
{
//Free unmanaged ressources here.
}
}
/*
There are some other ways to do this described in these SO links.
http://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue
More on Channel.Close() => http://msdn.microsoft.com/en-us/library/ms405496.aspx
And a WCF Proxy Helper => http://erwyn.bloggingabout.net/2006/12/09/WCF-Service-Proxy-Helper/
And a IL Injected Wrapper => http://corneliutusnea.wordpress.com/2007/08/20/building-a-reusable-clientbase-proxy/
*/
//http://stackoverflow.com/questions/5071183/wcf-serviceclient-dispose
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
}
//http://www.codeproject.com/Tips/197531/Do-not-use-using-for-WCF-Clients
public static class WcfExtensions
{
public static void Using<T>(this T client, Action<T> work)
where T : ICommunicationObject
{
try
{
work(client);
client.Close();
}
catch (CommunicationException e)
{
client.Abort();
}
catch (TimeoutException e)
{
client.Abort();
}
catch (Exception e)
{
client.Abort();
throw;
}
}
// Mine
public static void GracefullyClose<T>(this T client) where T : ICommunicationObject
{
try
{
client.Close();
}
catch (CommunicationException)
{
client.Abort();
}
catch (TimeoutException)
{
client.Abort();
}
catch (Exception)
{
client.Abort();
throw;
}
}
}
USAGE:
new SomeClient().Using(channel => {
channel.Login(username, password);
});
new ChannelFactory<ISomeService>().Using(channel => {
channel.Login(username, password);
});
public void Dispose()
{
try
{
_channel.GracefullyClose();
}
catch (Exception ex)
{
Log.Error("Dispose Error", ex);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment