【发布时间】:2019-11-13 22:08:45
【问题描述】:
我有一个线程正在运行,它从相机中抓取图像,保存它们,然后更新图片框以显示该位图。当我想退出应用程序时,我将 bool exitApplication 设置为 true,但它永远不会在 join() 调用中返回。
public void GrabThread()
{
Bitmap copyBmp;
while (!exitApplication)
{
mImage = m_camera.GrabImage();
SaveImage();
copyBmp = (Bitmap)mImage.bmp.Clone();
if (pictureBox1.InvokeRequired)
{
pictureBox1.Invoke(new MethodInvoker(
delegate ()
{
pictureBox1.Image = copyBmp;
}));
}
else
{
pictureBox1.Image = copyBmp;
}
m_camera.ReleaseImage();
}
}
我的退出代码:
exitApplication = true;
threadGrab.Join();
m_camera.Stop();
Close();
当我从 Debug 菜单调用 Break All 时,线程挂起
pictureBox1.Invoke(new MethodInvoker(
delegate ()
{
pictureBox1.Image = copyBmp;
}));
为什么?我怎样才能防止这种情况发生?目前我必须在线程上调用 Abort() 才能退出它。
【问题讨论】:
-
Invoke将在 UI 线程上执行它的调用。如果该线程很忙,它将阻塞。简单的解决方案是将后台与 UI 代码分离,并使用await等待后台代码完成而不会阻塞,然后再返回 UI 线程。 -
好的,我明白了,由于我在Button Clicked方法中,UI Thread正在等待。在等待时,永远不会调用调用,从而导致死锁。 Await() 做什么,或者更确切地说,如何使用它?我现在更改了我的代码,以便在抓取线程停止时使用 Environment.Exit(0)。
-
相反,
Invoke被调用,但 UI 线程已经被threadGrab.Join();阻塞。这会导致死锁 - 后台线程正在等待 UI 线程解除阻塞,但 那个 线程又在等待后台线程完成。 -
至于如何修复代码,需要后台运行的部分是什么?
标签: c# multithreading delegates