如何缓存IDisposable对象 [英] How to cache an IDisposable object

查看:52
本文介绍了如何缓存IDisposable对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这个课程:

public class StreamEntity : IPersistableEntity, IDisposable
{
     public Stream Stream { get; set; }

     public void Dispose()
     {
           if(Stream != null) Stream.Dispose();
     }
}

现在让我们说我想在某种类型的缓存中存储此类的实例,例如

Now let's say I want to store an instance of this class in some kind of cache, like MemoryCache.

将实体存储在缓存中后,我将其废弃.

After storing the entity in the cache, I proceed to dipose it.

一段时间后,使用者尝试检索相同的实体,所以我从缓存中获取它,但是有一个小问题...对象被处置,因此我无法读取其 Stream 属性(还记得我们将其缓存后丢弃了吗?)

After some time, a consumer tries to retrieve the same entity so I fetch it from the cache, but there is a little problem... The object is disposed, so I cannot read its Stream property (Remember we disposed it after caching it?)

现在,解决此问题的一种方法是从不处置缓存的实体.这似乎是合乎逻辑的,因为应该将它们保留在内存中,但是到期后会发生什么呢?

Now, one way to solve this, is to never dispose the cached entities. This seems logical since they should be kept alive in memory, but what happens after expiration?

具体来说,当 MemoryCache 自动删除已过期的对象时,会丢弃它吗?

Specifically, when MemoryCache automatically removes an object that has expired, will it dispose it?

根据在驱逐时,MemoryCache会丢弃IDisposable项目? MemoryCache 不会处理其缓存的项目.

According to Will MemoryCache dispose IDisposable items when evicted?, MemoryCache will not dispose its cached items.

知道这一点,如何缓存一次性对象?如果我无法控制实体的驱逐,应何时处置?

Knowing this, How can I cache a disposable object? When should I dispose the entities if I'm not in control of their eviction?

推荐答案

您正确的认为 MemoryCache 不会调用 Dispose ,但是您可以告诉它在收回项目时调用处置".

You are correct that MemoryCache does not call Dispose, however you can tell it to call Dispose when evicting a item.

static void Main(string[] args)
{
    var policy = new CacheItemPolicy
    {
        RemovedCallback = RemovedCallback,
        SlidingExpiration = TimeSpan.FromMinutes(5)
    };
    Stream myStream = GetMyStream();
    MemoryCache.Default.Add("myStream", myStream, policy);
}

private static void RemovedCallback(CacheEntryRemovedArguments arg)
{
    if (arg.RemovedReason != CacheEntryRemovedReason.Removed)
    {
        var item = arg.CacheItem.Value as IDisposable;
        if(item != null)
            item.Dispose();
    }
}

上面的示例创建一个 Stream 对象,如果在5分钟内未使用它,则会在其上调用 Dispose().如果由于 Remove()调用删除了该项目或通过 Set(调用覆盖了该项目)而删除了流,它将 调用了 Dispose().

The above example creates a Stream object and if it is unused for 5 minutes it will have Dispose() called on it. If the stream is removed due to a Remove( call removing the item or a Set( call overwriting the item it will not have Dispose() called on it.

这篇关于如何缓存IDisposable对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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