Error: Invalid thread operation

Asked

Viewed 4,833 times

2

I’m trying to open the Webcam, but every time I try to execute the method iniciarwebcam() it returns me the error:

There was an exception of type "System.Invalidoperationexception" in System.Windows.Forms.dll, but it was not manipulated in the code of the user Invalid cross-threaded operation: 'Form1' control accessed from a thread that is not the one it was created in.

As I am learning C# now I have to find a solution that fits with mine

Error happens on line:

video.NewFrame += (s, b) => pictureBox1.Image = (Bitmap)b.Frame.Clone();

Code:

using AForge.Video.DirectShow;

public void  inciarwebcam() 
{

    FilterInfoCollection filtro = new FilterInfoCollection(FilterCategory.VideoInputDevice);

    if (filtro != null)
    {
        video = new VideoCaptureDevice(filtro[0].MonikerString);
        video.NewFrame += (s, b) => pictureBox1.Image = (Bitmap)b.Frame.Clone();
        video.Start();
    }
}

public void fecharwebcam() 
{

    if (video != null && video.IsRunning ) {

        video.SignalToStop();
        video = null;

    }

}

public VideoCaptureDevice video;

private void button6_Click(object sender, EventArgs e)
{
    if (button6.Text == "Desativado")
    {
        button6.Text = "Ativado";
        button6.BackColor = Color.Green;
       ard.Open();
        inciarwebcam();
    }
    else
    {
        button6.BackColor = Color.DarkRed;
        button6.Text = "Desativado";
        ard.Close();

        fecharwebcam();
    };
}

2 answers

4


Possibly the event NewFrame is asynchronous, and when trying to access the pictureBox1 the exception is fired.

You can use an invoke for this:

video.NewFrame += (s, b) => pictureBox1.Invoke((MethodInvoker) delegate {
                            pictureBox1.Image = (Bitmap)b.Frame.Clone();
            });

It seems to me that this way can be a little slow, since each frame will go in the other thread show the image. It’s just a starting point, if you have documentation of what you’re using can make things easier


Edit:

I have a form with the same library, and in the example I used, there’s a variable in the form, which takes the image, and then it’s applied to picturebox:

Bitmap Imagem;
private void video_NovoFrame(object sender, NewFrameEventArgs eventArgs)
{
    Imagem = (Bitmap)eventArgs.Frame.Clone();
    pbCaptura.Image = Imagem;
}
  • 1

    Man, thank you so much! It worked and I don’t have the documentation... I picked up on a tutorial but still, thank you!

  • look at the @Danielsouto update, I think this second way gets better

0

It can always validate whether the control needs to effectively evoke the Invoke:

video.NewFrame += (s, b) => 
{
    if(pictureBox1.InvokeRequired)
        pictureBox1.Invoke(new Action(() => { pictureBox1.Image = (Bitmap)b.Frame.Clone(); }));
    else pictureBox1.Image = (Bitmap)b.Frame.Clone();
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.