要显示摄像机的实时流,启动事件处理程序。此事件的代码是:
private void onFrameEventFocusCam(object sender, EventArgs e)
{
uEye.Camera Camera = sender as uEye.Camera;
Int32 s32MemID;
Camera.Memory.GetActive(out s32MemID);
// Read Camera bitmap
Bitmap bitmap;
Camera.Memory.ToBitmap(s32MemID, out bitmap);
Dispatcher.Invoke(new Action(() =>
{
// Convert bitmap to WPF-Image
var bmp = new Bitmap(bitmap);
var hBitmap = bmp.GetHbitmap();
System.Windows.Media.ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image_fokus.Source = wpfBitmap;
image_fokus.Stretch = System.Windows.Media.Stretch.Fill;
image_fokus.StretchDirection = StretchDirection.Both;
DeleteObject(hBitmap);
bitmap.Dispose();
}));
GC.Collect();
}
现在,当我关闭相机时(见下面的代码),它会给我一条错误消息“线程从等待状态中断”。返回,调试器跳转到Dispatcher.Invoke-Code(见上文)。
当我取消注释MessageBox.Show(“0”)时,错误显示为 NOT ,按下此消息框的OK按钮后一切正常。
这是关闭相机和事件处理程序的代码:
// Close Camera
Camera.Acquisition.Stop(uEye.Defines.DeviceParameter.Force);
Camera.EventFrame -= onFrameEventFocusCam; // remove Event
// MessageBox.Show("0");
uEye.Defines.Status statusRet = 0;
statusRet = Camera.Exit();
有人知道我做错了什么以及如何避免这样的错误消息(没有消息框)?
谢谢!
执行以下步骤:
1)打开相机并调用 onFrameEventFocusCam 事件处理程序
2)图像有效并显示在GUI
上3)在主UI中,相机再次关闭,事件被禁用
4)由于某些原因(竞争条件?),同样的事件再次被重新激活
这是相机再次关闭的主线程的一部分:
else
{
// Close Camera
uEye.Defines.Status statusRet = 0;
statusRet = Camera.Acquisition.Stop(uEye.Defines.DeviceParameter.DontWait);
Camera.EventFrame -= onFrameEventFocusCam; // remove Event
statusRet = Camera.Exit();
} // end of else..
在“}”之后,以下事件再次被重新激活,并再次跳转到onFrameEventFocusCam!
private void onFrameEventFocusCam(object sender, EventArgs e)
{
uEye.Camera Camera = sender as uEye.Camera;
Int32 s32MemID;
Camera.Memory.GetActive(out s32MemID);
// Read Camera bitmap
Bitmap bitmap;
Camera.Memory.ToBitmap(s32MemID, out bitmap);
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
// Convert bitmap to WPF-Image
var bmp = new Bitmap(bitmap);
var hBitmap = bmp.GetHbitmap();
System.Windows.Media.ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image_fokus.Source = wpfBitmap;
image_fokus.Stretch = System.Windows.Media.Stretch.Fill;
image_fokus.StretchDirection = StretchDirection.Both;
DeleteObject(hBitmap);
bitmap.Dispose();
}));
GC.Collect();
}
答案 0 :(得分:1)
当你的程序正在执行"关闭相机时,会发生什么?代码,摄像头引发了一个事件,导致调用Dispatcher.Invoke()
方法,从而导致事件提升线程等待,直到UI线程可以处理被调用的方法。
据推测,您正在执行"关闭相机" UI线程中的代码(例如,响应用户输入,如按钮点击或某事)。这意味着在您使用"关闭相机"完成后,事件提升线程无法继续。码。但代码所做的最后一件事就是调用Camera.Exit()
。这显然会导致相机库中断正在等待的事件引发线程,导致异常。
当您致电MessageBox.Show()
时,异常就会消失,因为这会导致Dispatcher
抽取窗口消息,包括处理调用Dispatcher.Invoke()
调用方法的消息。这会取消阻塞事件处理程序,让它在到达调用Camera.Exit()
之前返回,从而避免相机库中断线程。
我认为在这种情况下修复它的最简单方法就是调用Dispatcher.BeginInvoke()
(或更新的Dispatcher.InvokeAsync()
)方法。这将导致方法调用异步排队,允许事件处理程序立即返回,而无需等待UI线程。