0

I am having some timing issues with the following code. Basically I have "recordingOn", when True, it's suppose to start writing frames to file. In the below program, when I sometimes do Stop_Button_Click, I get an exception on "writer1.Write(frame1);" line, this is likely because it's doing so after I've already done dispose(). How do I synchronize this? thanks!

private bool recordingOn = false;

private void ConnectCameras_Button_Click(object sender, EventArgs e)
{
    if (!captureInProgress) //Start cameras streaming
    {
        camera1Capture.ImageGrabbed += ProcessFrame;
        camera1Capture.Start();
    }
    else //Stop cameras streaming
    {
        camera1Capture.Stop();
        imageBox1.Image = null;
        camera1Capture.ImageGrabbed -= ProcessFrame;
    }
    captureInProgress = !captureInProgress;
}

private void ProcessFrame(object sender, EventArgs arg)
{
    camera1Capture.Retrieve(frame1);
    imageBox1.Image = frame1;

    if (recordingOn)
    {
        try
        {
            writer1.Write(frame1);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

private void Stop_Button_Click(object sender, EventArgs e)
{
    // Doing other stuff...
    recordingOn = false;
    writer1.Dispose();      
}
2
  • my mistake, writer1.Dispose should also have been in the lock, have updated the answer, can you try now. Commented Mar 7, 2019 at 0:22
  • Could you please provide a minimal reproducible example? Commented Mar 7, 2019 at 2:34

1 Answer 1

1

The basic issue is of shared variable across multiple threads. Please use lock to control access to shared variable. Lock ensures that at one time only one thread can access a variable.

private bool recordingOn = false;
private static object _lock = new Object();

private void ConnectCameras_Button_Click(object sender, EventArgs e)
{
    if (!captureInProgress) //Start cameras streaming
    {
        camera1Capture.ImageGrabbed += ProcessFrame;
        camera1Capture.Start();
    }
    else //Stop cameras streaming
    {
        camera1Capture.Stop();
        imageBox1.Image = null;
        camera1Capture.ImageGrabbed -= ProcessFrame;
    }
    captureInProgress = !captureInProgress;
}

private void ProcessFrame(object sender, EventArgs arg)
{
    camera1Capture.Retrieve(frame1);
    imageBox1.Image = frame1;
    lock (_lock)
    {
    if (recordingOn)
    {
        try
        {
            writer1.Write(frame1);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    }
}

private void Stop_Button_Click(object sender, EventArgs e)
{
    // Doing other stuff...
    lock (_lock)
    {
      recordingOn = false;
      writer1.Dispose();   
    }

}
Sign up to request clarification or add additional context in comments.

4 Comments

I tried this, but unfortunately it didn't work. I still got issue at "Write".
@golu my mistake, writer1.Dispose should also have been in the lock, can you try now.
Ok thanks, will try. So does this mean, execution in a thread will continue past the lock section? like does it skip over writer1.Dispose that was after the lock section?
lock makes the code under if atomic. In earlier case where I was locking and setting the flag to false, then disposing outside lock, what can happen is that the flag is set to false and lock released. Now a different thread takes over and again sets the flag to true and maybe starts writing, then our original thread gets cpu and tries to dispose. Basically in a multi-threading environment, execution can be interrupted at any instruction, that is why we need to sync access to shared data/resources.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.