Should I implement IDisposable on a singleton?

余生颓废 提交于 2019-12-19 09:58:24

问题


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;
      }
   }
} 

回答1:


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;
     }
   }
} 



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/22140593/should-i-implement-idisposable-on-a-singleton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!