多线程之间的控制/同步变量C#

时间:2019-03-06 04:33:51

标签: c# multithreading thread-safety

以下代码出现一些计时问题。基本上我有“ recordingOn”,当为True时,应该开始将帧写入文件。在下面的程序中,有时执行Stop_Button_Click时,出现“ writer1.Write(frame1);”异常。行,这很可能是因为这样做是在我已经完成dispose()之后执行的。我该如何同步呢?谢谢!

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();      
}

1 个答案:

答案 0 :(得分:1)

基本问题是多个线程之间的共享变量。请使用lock来控制对共享变量的访问。 Lock确保一次只能有一个线程访问变量。

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();   
    }

}