Question

I've got two picture boxes on the main form, one is a video stream from a webcam mounted on top of a robot, the other is some user feedback which is updated every now and again with a graph of what it thinks it can see (named map). Both pictures can be updated by any of the threads. How do I go about updating these pictures safely?

At the moment my Main Form has two methods with a delegate call in them like this:

public partial class MainForm : Form
{

public void videoImage(Image image)
{
    this.VideoViewer.Image = image;
    if (this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(delegate { videoImage(image); }));
     }
}

public void mapImage(Image image)
{
    this.VideoViewer.Image = image;
    if (this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(delegate { mapImage(image); }));
    }
}

}

The main robot thread has this in it:

public delegate void videoImageReady(System.Drawing.Image image);
public event videoImageReady videoImage;

and a third thread has

public delegate void mapImageReady(System.Drawing.Image image);
public event mapImageReady mapImage;

I'm not sure if this is the correct way to do it, or if there are better ways, this is just the way I found (but it doesn't work) I found this example and this example, but I didn't understand them completely, so I'm not entirely sure how to implement them.

Thanks in advance.

Was it helpful?

Solution

The InvokeRequired check and it's handling is there to make sure the UI controls are updated on the UI thread and not from your own thread. Your code seens to have all the bits but your code is in the wrong order. I take one example:

// this is called from any thread
public void videoImage(Image image)
{
    // are we called from the UI thread?
    if (this.InvokeRequired)
    {
        // no, so call this method again but this
        // time use the UI thread!
        // the heavy-lifting for switching to the ui-thread
        // is done for you
        this.Invoke(new MethodInvoker(delegate { videoImage(image); }));
    } 
    else 
    {
        // we are now for sure on the UI thread
        // so update the image
        this.VideoViewer.Image = image;
    }
}

OTHER TIPS

Should be:

if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate { videoImage(image); }));
return;
}

otherwise you'll call the MethodInvoker delegate and then the normal one afterwards.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top