在Dispose()中调用的Leap Motion Controller.RemoveListener()挂起



我已经开始开发一个Leap Motion应用程序,这让我发疯了。每当我退出应用程序时,负责清理 Leap 运动控制器的代码都会挂在我身上。

public void CleanUp()
{
    _lmController.RemoveListener(_lmListener);
    _lmController.Dispose();
}

我在演示器类的主线程中创建控制器和侦听器:

public MainViewPresenter(IMainView view, IApplicationController applicationController)
{
    _view = view;
    _applicationController = applicationController;
    _view.Presenter = this;
    _lmListener.Frame += _lmListener_Frame;
    _lmController.AddListener(_lmListener);
}

Cleanup() 方法也是在视图的 FormClosing 事件上调用的表示器方法。奇怪的是,当我从 _listener_Frame() 调用它时,它工作得很好,它运行在一个单独的、Leap Motion 创建的无名线程上!

_lmListener_Frame()本身驻留在演示者中。它只是从_lmController获取数据,创建一个视图模型并将其发送到视图,而视图又使用Invoke来更新显示数据。

我尝试在Dispose()中调用清理内容(视图和演示者(当然不是多余的)),但这也不起作用。

承认我不是线程专家,但我看不出这里发生了什么冲突,以及为什么 RemoveListener 从控制器线程工作,而不是从主线程工作,侦听器实际上是添加的。任何帮助不胜感激!

溶液

完全是偶然的,我今天找到了解决方案!事实证明,"Invoke"调用是罪魁祸首,它应该一直都是BeginInvoke,尽管WinForms设置指南中没有提到这一点。我猜它导致了控制器线程的死锁,并且在第一次 GUI 更新后它必然会崩溃。

在Windows表单应用程序中,以下内容对我有用:

    protected override void Dispose(bool disposing)
    {
        try
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
                this.controller.RemoveListener(this.listener);
                this.controller.Dispose();
            }
        }
        finally
        {
            base.Dispose(disposing);
        }
    }
}

不过,我不久前写了它,不记得为什么它需要比你尝试的更复杂。(完整示例在这里:https://developer.leapmotion.com/documentation/csharp/devguide/Project_Setup_WinForms.html)

最新更新