如何停止事件处理程序?
How to stop event-handler?
为了显示摄像机的实时流,启动了事件处理程序。本次活动的代码是:
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();
}
现在,当我关闭相机(见下面的代码)时,它会返回一条错误消息 "Thread was interrupted from a waiting state.",调试器跳转到 Dispatcher.Invoke-代码(见上文)。
当我取消对 MessageBox.Show("0") 的注释时,错误不再显示 NOT,按下此消息框的确定按钮后一切正常。
这是关闭相机和事件处理程序的代码:
// 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) 在 Main 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();
}
发生的事情是,当您的程序正在执行 "close camera" 代码时,相机引发了一个事件,导致 Dispatcher.Invoke()
方法被调用,从而导致事件引发线程等待直到 UI 线程可以处理调用的方法。
推测您正在 UI 线程中执行 "close camera" 代码(例如,响应用户输入,如按钮点击或其他)。这意味着在您完成 "close camera" 代码之前,事件引发线程无法继续。但是代码做的最后一件事是调用 Camera.Exit()
。这显然会导致相机库中断正在等待的事件引发线程,从而导致异常。
调用 MessageBox.Show()
时异常消失,因为这会导致 Dispatcher
发送 window 消息,包括处理调用 [=] 的调用方法的消息10=]。这会解除事件处理程序的阻塞,让它 return 在你到达调用点 Camera.Exit()
之前,避免相机库中断线程的需要。
我认为在这种情况下修复它的最简单方法就是调用 Dispatcher.BeginInvoke()
(或较新的 Dispatcher.InvokeAsync()
)方法。这将导致方法调用异步排队,允许事件处理程序立即 return 而无需等待 UI 线程。
为了显示摄像机的实时流,启动了事件处理程序。本次活动的代码是:
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();
}
现在,当我关闭相机(见下面的代码)时,它会返回一条错误消息 "Thread was interrupted from a waiting state.",调试器跳转到 Dispatcher.Invoke-代码(见上文)。
当我取消对 MessageBox.Show("0") 的注释时,错误不再显示 NOT,按下此消息框的确定按钮后一切正常。
这是关闭相机和事件处理程序的代码:
// 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) 在 Main 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();
}
发生的事情是,当您的程序正在执行 "close camera" 代码时,相机引发了一个事件,导致 Dispatcher.Invoke()
方法被调用,从而导致事件引发线程等待直到 UI 线程可以处理调用的方法。
推测您正在 UI 线程中执行 "close camera" 代码(例如,响应用户输入,如按钮点击或其他)。这意味着在您完成 "close camera" 代码之前,事件引发线程无法继续。但是代码做的最后一件事是调用 Camera.Exit()
。这显然会导致相机库中断正在等待的事件引发线程,从而导致异常。
调用 MessageBox.Show()
时异常消失,因为这会导致 Dispatcher
发送 window 消息,包括处理调用 [=] 的调用方法的消息10=]。这会解除事件处理程序的阻塞,让它 return 在你到达调用点 Camera.Exit()
之前,避免相机库中断线程的需要。
我认为在这种情况下修复它的最简单方法就是调用 Dispatcher.BeginInvoke()
(或较新的 Dispatcher.InvokeAsync()
)方法。这将导致方法调用异步排队,允许事件处理程序立即 return 而无需等待 UI 线程。