无法访问已关闭的流

10

我正在尝试使用缓存应用程序块(Caching Application Block)来缓存一些图像(这些图像需要很长时间才能渲染)

  BitmapSource bitmapSource; ///some bitmap source already created
  _cache ///  Caching Application Block
  String someId; //id for this image, used as the key for the cache

  using (var stream = new MemoryStream())
    {
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Interlace = PngInterlaceOption.On;
        encoder.Frames.Add(BitmapFrame.Create(bitmapSource));             
        encoder.Save(stream);
        _cache.Add(someId, stream);
    }

然后使用以下方式加载它们:

imStream = (Stream)_cache.GetData(someId));
if (imStream != null)
{
    PngBitmapDecoder decoder = new PngBitmapDecoder(imStream,  BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    return decoder.Frames[0];  //return the bitmap source
}

但在加载期间,我在“new PngBitmapDecoder”行收到以下异常:

"无法访问已关闭的流。

我知道我在上面的代码中关闭了流,但不是_cache.Add()在退出之前通过序列化进行复制吗?序列化流的正确过程是什么?

谢谢!

2个回答

9
问题在于流(通过Dispose())在using块的结尾处关闭。您保留了对已关闭流的引用。
相反,将流的内容保存到缓存中:
_cache.Add(someId, stream.ToArray());

当您调用PngBitmapDecoder构造函数时,您需要创建一个新的MemoryStream来从该字节数组中读取。

7
但是_cache.Add()在退出时不是会通过序列化进行复制吗?
不一定。如果它是“进程内”的话,它只会存储对象引用;Stream 实际上并不太可序列化(Stream 是一根水管,而不是一个桶)。
你想要存储 BLOB——而不是 Stream:
    _cache.Add(someId, stream.ToArray());

...

byte[] blob = _cache.GetData(someId);
if(blob != null) {
    using(Stream inStream = new MemoryStream(blob)) {
         // (read)
    } 
}

谢谢!两个答案都很好,我只是标记了先到的那一个 :)我喜欢主机/桶参考。 - moogs
2
@moogs - 实际上这个先到了 (04:55:29 vs 04:46:05)。 - Alconja
这很奇怪...这篇帖子之前的"xx分钟前回答"时间比现在高。嗯。 - moogs
1
我向您保证,即使使用♦,我也无法改变那个。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接