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