如何停止事件处理程序?

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 线程。