I have a windows service, which contains a singleton which in turn uses some loggers, message queue listeners and so on. Those classes implements IDisposable
. Should I implement IDisposable
in singleton itself or do something else to ensure that after service stop/crashing everything will be okay with native resources?
The singleton is implemented like this:
public class Temp
{
private static readonly Lazy<Temp> instance = new Lazy<Temp>(() => new Temp());
private Temp()
{
// create IDisposable objects which use native resources
}
public static Temp Instance
{
get
{
return instance.Value;
}
}
}
I'd rather not implement IDisposable
on singleton: IDisposable
provokes developer to Dispose the (single) instance:
using(var temp = Temp.Instance) {
...
}
which leads to (possible) crash in some other part of the application (since the single Temp
instance has been disposed):
Temp.Instance.SomeFucntion(); // <- possible fail, since Temp.Instanceis disposed
In some rare case if you have to release some resouces aquired, I'd use ProcessExit
event
public class Temp {
private static readonly Lazy<Temp> instance = new Lazy<Temp>(() => new Temp());
private void OnProcessExit(Object sender, EventArgs e) {
// Release native resource if required:
// some resources e.g. files will be closed automatically,
// but some e.g. transactions should be closed (commit/rollback) manually
try {
...
}
finally {
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;
}
}
private Temp() {
// create IDisposable objects which use native resources
// If you have to release some resouces on exit
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
}
public static Temp Instance {
get {
return instance.Value;
}
}
}
No; Singleton shouldn't implement IDisposable
. What if someone disposes the instance prematurely when others are in need of that?
Also note that implementing IDisposable
will not help you when your service is crashed/stopped. You'll have to dispose it manually! but you can't find right time to do it.
If a type will be returned from a factory that will sometimes need to be cleaned up when the caller is done with them, the type should implement IDisposable
. If a particular factory returns a shared singleton object that doesn't actually need any resources, the object returned by the factory should have a Dispose
method which silently does nothing. If the factory needs to provide access to a shared singleton resources (e.g. an immutable bitmap stored in a GDI object), it should return a wrapper which will notify the factory when it its Dispose
method is called; the factory can then maintain a reference count of wrapper objects and clean up the resource once it knows that no more wrappers will be created and all existing wrappers have been disposed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With