处置单例实例(C#) [英] Disposing a singleton instance (C#)

查看:150
本文介绍了处置单例实例(C#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果单例实现IDisposable,则处置和重新创建实例的正确方法是什么?一种方法是保留_disposed标志并在Instance属性中检查它,但是我不确定这是正确的方法。一个简单的例子:

If a singleton implements IDisposable, what is the right way of disposing and re-creating an instance? One way would be to keep _disposed flag and check for it in the Instance property, but I'm not sure it is the right way to do this. A simple example:


public sealed class Singleton: IDisposable
{
   private static Singleton _instance;
   private object _lock;
   private UnmanagedResource _unmanaged;
   private bool _disposed;

   private Singleton()
   {
      _unmanaged = new UnmanagedResource();
      _disposed  = false;
      _lock      = new object();
   }

   public UnmanagedResource Unmanaged { get { return _unmanaged; } }

   public static Singleton Instance
   {
      get
      {
         if (_instance == null || _disposed)
         {
            lock (_lock)
            {
               if (_instance == null || _disposed)
               {
                  _instance = new Singleton();
               }
            }
         }
         return _instance;
      }
   }

   public void Dispose()
   {
      _disposed = true;
      try
      {
         _unmanaged.Dispose();
      }
      finally
      {
         GC.SuppressFinalize(this);
      }
   }
}

所以这样的代码是可能(尽管,是的,我同意,这有点违背了拥有Singleton的目的):

So that code likes this is possible (though, yes I agree, it kind of defeats the purpose of having a Singleton):


Singleton.Instance.Dispose();
Singleton.Instance.Unmanaged.UseResource();   // Unmanaged shouldn't be null.

注意:无需过分强调Singleton和IDisposable之间的不兼容性,我明白了。当ApppDomain卸载时,我需要Dispose方法来释放不受管理的资源。如果您对名为Singleton的此类有疑问,可以将其重命名为LoadBalancer。问题将保持不变。该LoadBalancer必须是可抛弃的,因为它的实例不属于任何人,但应妥善处置。

NOTE: There is no need to overemphasize incompatibility between Singleton and IDisposable, I understand it. I need Dispose method to free unmanaged resources when ApppDomain unloads. If you have a problem with this class being called Singleton, I can rename it LoadBalancer instead. The question will still remain the same. This LoadBalancer needs to be disposable, because it's instance does not belong to anyone, but should be properly disposed.

推荐答案

替换单例实例,您应该考虑一下您的设计。

if you need to replace the instance of a singleton, you should think about your design.

如果您真的认为应该这样做,我建议您使用2个对象...

if you REALLY think you should do this, i'd suggest to use 2 objects ...

一个单例对象,它充当代理,并且是真正的单例(生命周期结束==进程结束)

one singleton object that acts as a proxy, and is a real singleton (end of lifetime == end of process)

此对象需要您的单例功能所需要的公共成员,以及一个拥有真正实现对象的私有成员。所有其他成员都重定向到该实现的成员。

this object needs public members for everything your singleton is capable of, and one private member holding the real implementing object. all other members redirect to members of that implementation.

第二个对象是可以替换的一次性对象。确保只有您的单例对象会保留对此的引用...这样,无论是否有任何消费者对象都在该单例上保留了阻止您替换该对象的引用...这ref只会指向到代理

the second object is the disposable object that can be replaced. make sure that only your singleton object will ever hold a reference on that... this way it doesn't matter if any consumer object holds a reference on the singleton that would prevent you from replacing the object ... that ref will only point to a proxy

这篇关于处置单例实例(C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆