I'm trying to use the Caching Application Block to cache some images (these images take a long time to render)
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);
}
And then load them using:
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
}
But during the load, i get the following exception at that "new PngBitmapDecoder" line:
"Cannot access a closed Stream.
I understand I closed the stream in the above code, but isn't _cache.Add() making a copy (via Serialization) before it exits? What's the correct process of serializing the stream?
THanks!
The problem is that the stream is closed (via Dispose()
) at the end of the using
block. You retain a reference to the closed stream.
Instead, save the contents of the stream to your cache:
_cache.Add(someId, stream.ToArray());
When you call the PngBitmapDecoder
constructor, you'll have to create a new MemoryStream
to read from that byte array.
but isn't _cache.Add() making a copy (via Serialization) before it exits?
Not necessarily. If it is "in process" it will just store the object reference; Stream
isn't really very serializable anyway (a Stream
is a hose, not a bucket).
You want to store the BLOB - not the Stream
:
_cache.Add(someId, stream.ToArray());
...
byte[] blob = _cache.GetData(someId);
if(blob != null) {
using(Stream inStream = new MemoryStream(blob)) {
// (read)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With