如何管理缓存的IDisposable对象?

我有一个创建成本很高的对象,它使用了一些非托管资源,必须在完成IDisposable()时显式释放这些资源。 我希望缓存这些昂贵资源的实例,以便将创建成本降到最低,但我无法知道如何处理这种处置。

如果使用这些对象的方法负责处理,那么我最终会在缓存中放置实例,然后必须重新创建这些实例,从而击败缓存点。 如果我不在使用它们的方法中处理对象,那么它们永远不会被丢弃。 我想我可以在将它们从缓存中取出时处理它们,但是最终可能会丢弃仍在使用某个方法的实例。

让它们超出范围并由垃圾收集器收集并在那时释放资源是否有效? 这感觉不对,并且反对他们被丢弃的想法...


一次性物品总是需要有一个明确的所有者负责处理它们。 但是,这并不总是创造它们的对象。 此外,所有权可以转移。

意识到这一点,解决方案变得明显。 不要处置,回收! 您不仅需要一种从缓存中获取资源的方法,还需要一种方法来返回它。 此时,缓存又是所有者,并且可以选择保留该资源以备将来使用或处置它。

   public interface IDisposableItemCache<T> : IDisposable
      where T:IDisposable 
   {
      /// <summary>
      /// Creates a new item, or fetches an available item from the cache.
      /// </summary>
      /// <remarks>
      /// Ownership of the item is transfered from the cache to the client.
      /// The client is responsible for either disposing it at some point,
      /// or transferring ownership back to the cache with
      /// <see cref="Recycle"/>.
      /// </remarks>
      T AcquireItem();

      /// <summary>
      /// Transfers ownership of the item back to the cache.
      /// </summary>
      void Recycle(T item);

   }

编辑:我只是注意到,这个想法也存在于Spring中,它被称为对象池。 他们的BorrowObjectReturnObject方法与我的例子中的方法相匹配。


(错)引用Raymond Chen:没有过期策略的每个缓存都是泄漏

因此,请设置明确的缓存过期策略,并让缓存按正常情况处理它们。 这仍然会导致应用程序关闭被处理。

如果您的非托管资源由进程拥有,您可以让进程在关闭时释放它们。

如果非托管资源属于进程,则需要检测关闭并明确地配置缓存的元素。

如果您无法可靠地检测到进程关闭,并且托管资源非常昂贵,那么非托管资源不会将托管资源与非托管资源分开,并让缓存仅保留托管资源。

当非托管资源非常昂贵而需要缓存时,它们不属于该进程,并且无法可靠地检测到进程关闭,并且无法泄漏它们,则无法解决问题。


首先,包装本地资源的类型应该可以定型,而不只是一次性的。 更好的是,使用SafeHandle来包装原生资源。

除非有人明确说明他们已经完成了该物品并且可以处置该物品,否则我认为最好让GC处理它。 请注意,它必须是可以终结的,否则GC不会再给它第二眼。

链接地址: http://www.djcxy.com/p/9227.html

上一篇: How to manage IDisposable Objects that are cached?

下一篇: Singleton with finalizer but not IDisposable