Last active
August 29, 2015 14:00
-
-
Save romeshniriella/11278527 to your computer and use it in GitHub Desktop.
How to properly close and dispose using an extension method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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/ | |
*/ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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