Не удается получить доступ к закрытому потоку - PullRequest
10 голосов
/ 25 февраля 2010

Я пытаюсь использовать Блок приложения кэширования для кэширования некоторых изображений (эти изображения отнимают много времени)

  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 голосов
/ 25 февраля 2010

Проблема в том, что поток закрывается (через Dispose()) в конце блока using. Вы сохраняете ссылку на закрытый поток.

Вместо этого сохраните содержимое потока в свой кэш:

_cache.Add(someId, stream.ToArray());

Когда вы вызываете конструктор PngBitmapDecoder, вам нужно создать новый MemoryStream для чтения из этого байтового массива.

6 голосов
/ 25 февраля 2010

но разве _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)
    } 
}
...