【问题标题】:Control/Sync variable between multiple threads c#多线程c#之间的控制/同步变量
【发布时间】:2019-03-06 04:33:51
【问题描述】:

我在使用以下代码时遇到了一些时间问题。基本上我有“recordingOn”,当为真时,假设开始将帧写入文件。在下面的程序中,当我有时执行 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();      
}

【问题讨论】:

  • 我的错,writer1.Dispose应该也被锁定了,已经更新了答案,你现在可以试试。

标签: c# multithreading thread-safety


【解决方案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();   
    }

}

【讨论】:

  • 我试过这个,但不幸的是它没有用。我仍然在“写”时遇到问题。
  • @golu 我的错,writer1.Dispose 应该也被锁了,你现在可以试试。
  • 好的,谢谢,会试试。那么这是否意味着线程中的执行将继续超过锁定部分?就像它跳过了锁部分之后的 writer1.Dispose 吗?
  • lock 使 if 原子下的代码。在较早的情况下,我锁定并将标志设置为 false,然后处理外部锁,可能发生的情况是标志设置为 false 并释放锁定。现在另一个线程接管并再次将标志设置为 true 并可能开始写入,然后我们的原始线程获取 cpu 并尝试处理。基本上在多线程环境中,任何指令都可以中断执行,这就是我们需要同步访问共享数据/资源的原因。
猜你喜欢
  • 2016-07-08
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 2017-12-08
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多