servicestack 如何在ServiceStack中处置InMemory缓存结果,servicestack,servicestack" /> servicestack 如何在ServiceStack中处置InMemory缓存结果,servicestack,servicestack" />

servicestack 如何在ServiceStack中处置InMemory缓存结果

servicestack 如何在ServiceStack中处置InMemory缓存结果,servicestack,servicestack,我的ServiceStack API中有一个服务,通过实现IStreamWriter WriteTo(流)来处理图像结果。效果很好 为了优化处理,我添加了对InMemory缓存的支持,并在时间跨度内使结果过期。我关心的是IDispose。在缓存实现之前,我使用IDispose在返回后处理结果对象及其图像,但是使用inmemory cache它无法实现IDispose,否则数据将在从缓存中重新提取之前被擦除 问题是如何或在何处实现对缓存结果的处理?缓存是否会在过期时处理这些项?如果是这样的话,如何

我的ServiceStack API中有一个服务,通过实现IStreamWriter WriteTo(流)来处理图像结果。效果很好

为了优化处理,我添加了对InMemory缓存的支持,并在时间跨度内使结果过期。我关心的是IDispose。在缓存实现之前,我使用IDispose在返回后处理结果对象及其图像,但是使用inmemory cache它无法实现IDispose,否则数据将在从缓存中重新提取之前被擦除

问题是如何或在何处实现对缓存结果的处理?缓存是否会在过期时处理这些项?如果是这样的话,如何仅对来自缓存管理器的调用而不是http处理程序的调用实现Dispose

public class ImageResult : IDisposable, IStreamWriter, IHasOptions
{
    private readonly Image image;

    public void WriteTo(Stream responseStream)
    {
        image.Save(responseStream, imgFormat);
    }

    public void Dispose()
    {
        // if we dispose here, will be disposed after the first result is returned
        // want the image to be disposed on cache expiration
        //if (this.image != null)
        //    this.image.Dispose();
    }
}

public class ImageService : AssetService
{
    public object Get(ImageRequest request)
    {
        var cacheKey = ServiceStack.Common.UrnId.Create<ImageRequest>(request.id);

        if (Cache.Get<ImageResult>(cacheKey) == null)
        {
            Cache.Set<ImageResult>(cacheKey, GetImage(request), TimeSpan.FromMinutes(1));
        }

        return Cache.Get<ImageResult>(cacheKey);
    } 
    [...]
}
公共类ImageResult:IDisposable、IStreamWriter、IHasOptions
{
私有只读图像;
公共无效写入(流响应流)
{
image.Save(responseStream、imgFormat);
}
公共空间处置()
{
//如果我们在这里处理,将在返回第一个结果后处理
//希望在缓存过期时释放映像
//如果(this.image!=null)
//this.image.Dispose();
}
}
公共类ImageService:AssetService
{
公共对象获取(ImageRequest请求)
{
var cacheKey=ServiceStack.Common.UrnId.Create(request.id);
if(Cache.Get(cacheKey)==null)
{
Set(cacheKey,GetImage(请求),TimeSpan.frommins(1));
}
返回Cache.Get(cacheKey);
} 
[...]
}

通过快速查看ServiceStack,您可以看到缓存项过期时没有可挂接的事件或回调。考虑使用它可以提供类似的缓存功能,特别是您可以在过期和/或删除时使用更改监视器进行回调。 另一种选择是:从SS的缓存源代码创建自己的源代码,为您提供回调

一旦有了回调,就可以从那里调用
Dispose()
,但正如您所说的,您不希望
ImageResult
是一次性的,而是允许访问它的
Image
属性,并自己从过期回调中处理它。您可以围绕.net映像包装一个类,以便进行单元测试(避免在测试中使用真实的映像对象)

编辑:实际上。。见下文(*),这将造成混乱

另一方面,我将对Get()方法做一些细微的更改。最后一次调用Cache.Get()是多余的。即使您使用的是内存缓存,您仍然希望最小化对它的访问,因为它可能比看起来慢(需要使用锁来同步来自多个线程的内存访问)


通过快速查看ServiceStack,您可以看到缓存项过期时没有可挂接的事件或回调。考虑使用它可以提供类似的缓存功能,特别是您可以在过期和/或删除时使用更改监视器进行回调。 另一种选择是:从SS的缓存源代码创建自己的源代码,为您提供回调

一旦有了回调,就可以从那里调用
Dispose()
,但正如您所说的,您不希望
ImageResult
是一次性的,而是允许访问它的
Image
属性,并自己从过期回调中处理它。您可以围绕.net映像包装一个类,以便进行单元测试(避免在测试中使用真实的映像对象)

编辑:实际上。。见下文(*),这将造成混乱

另一方面,我将对Get()方法做一些细微的更改。最后一次调用Cache.Get()是多余的。即使您使用的是内存缓存,您仍然希望最小化对它的访问,因为它可能比看起来慢(需要使用锁来同步来自多个线程的内存访问)


我会给这一个镜头和更新,有趣的是,有时我们忘记了好的ol'析构函数。(是的,确实是多余的,最好按照建议返工。)酷。多余get的一个(极端)示例是在第一次调用中返回对象,在第二次调用中返回null,因为它在两次调用之间过期。我将对此进行一次尝试和更新,有趣的是,有时我们会忘记好的ol'析构函数。(是的,确实是多余的,最好按照建议返工。)酷。多余get的一个(极端)示例是在第一次调用中返回对象,在第二次调用中返回null,因为它在两次调用之间过期。
    var imageResult = Cache.Get<ImageResult>(cacheKey);
    if (imageResult == null)
    {
        imageResult = GetImage(request);
        Cache.Set<ImageResult>(cacheKey, imageResult, TimeSpan.FromMinutes(1));
    }

    return imageResult;
    ~ImageResult()
    {
        image.Dispose();
    }