C# Serialization Surrogate - Cannot access a disposed object
- by crushhawk
I have an image class (VisionImage) that is a black box to me. I'm attempting to serialize the image object to file using Serialization Surrogates as explained on this page. Below is my surrogate code.
sealed class VisionImageSerializationSurrogate : ISerializationSurrogate
{
public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
{
VisionImage image = (VisionImage)obj;
byte[,] temp = image.ImageToArray().U8;
info.AddValue("width", image.Width);
info.AddValue("height", image.Height);
info.AddValue("pixelvalues", temp, temp.GetType());
}
public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
VisionImage image = (VisionImage)obj;
Int32 width = info.GetInt32("width");
Int32 height = info.GetInt32("height");
byte[,] temp = new byte[height, width];
temp = (byte[,])info.GetValue("pixelvalues", temp.GetType());
PixelValue2D tempPixels = new PixelValue2D(temp);
image.ArrayToImage(tempPixels);
return image;
}
}
I've stepped through it to write to binary. It seems to be working fine (file is getting bigger as the images are captured). I tried to test it read the file back in. The values read back in are correct as far as the "info" object is concerned. When I get to the line
image.ArrayToImage(tempPixels);
It throws the "Cannot access a disposed object" exception. Upon further inspection, the object and the resulting image are both marked as disposed.
My code behind the form spawns an "acquisitionWorker" and runs the following code.
void acquisitionWorker_LoadImages(object sender, DoWorkEventArgs e)
{
// This is the main function of the acquisition background worker thread.
// Perform image processing here instead of the UI thread to avoid a
// sluggish or unresponsive UI.
BackgroundWorker worker = (BackgroundWorker)sender;
try
{
uint bufferNumber = 0;
// Loop until we tell the thread to cancel or we get an error. When this
// function completes the acquisitionWorker_RunWorkerCompleted method will
// be called.
while (!worker.CancellationPending)
{
VisionImage savedImage = (VisionImage) formatter.Deserialize(fs);
CommonAlgorithms.Copy(savedImage, imageViewer.Image);
// Update the UI by calling ReportProgress on the background worker.
// This will call the acquisition_ProgressChanged method in the UI
// thread, where it is safe to update UI elements. Do not update UI
// elements directly in this thread as doing so could result in a
// deadlock.
worker.ReportProgress(0, bufferNumber);
bufferNumber++;
}
}
catch (ImaqException ex)
{
// If an error occurs and the background worker thread is not being
// cancelled, then pass the exception along in the result so that
// it can be handled in the acquisition_RunWorkerCompleted method.
if (!worker.CancellationPending)
e.Result = ex;
}
}
What am I missing here? Why would the object be immediately disposed?