A Primer on Using Delegates to Display Images

When using EasyImages, you will often be assigning an image to a control that accepts an image, for example, pictureBox1.Image = picture. While this will work most of the time, Windows will occassionally generate a somewhat cryptic exception:

'System.InvalidOperationException: Object is currently in use elsewhere. at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)'

The problem is that we are trying to update the image held by this control in the wrong thread. The solution is to test to see if we are in the correct thread, and if not, to use a delegate to ensure that we are updating the image in the correct thread. Note that this is how .NET works, and this problem (and solution) is not unique to EasyImages.

Lets see how to solve this problem for a PictureBox control. pbox and image are the names of the instances of a PictureBox and an Bitmap accordingly.

First, we would declare a delegate that looks something like this:

private delegate void SetPictureBoxImage(PictureBox pbox, Bitmap image); // the delegate

Second, we would include a function something like the one below. This function checks to see what thread we are in, and invokes the above delegate if we are in the wrong thread. If we are in the correct thread, it assigns the image to the picture box:

public void RecievedImageToControl(PictureBox icontrol, Image image)
  if (icontrol.InvokeRequired) // are we in the wrong thread?
    SetPictureBoxImagetheDelegate = new SetPictureBoxImage(RecievedImageToControl);
    BeginInvoke(theDelegate, new object[] { icontrol, image })// call the function in the correct thread
    icontrol.Image = image; // we are in the correct thread, so assign the image

Finally, when we need to actually display an image in a picture box, we just invoke the above function:

this.RecievedImageToControl(pictureBox1, image);

Examples of how this works in practice can be seen in the tutorials. The Camera Minimal tutorial is a good place to start.