首页 文章

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

提问于
浏览
0

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

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事件上调用的presenter方法 . 奇怪的是,当我从 _listener_Frame() 调用它时它完全正常,它运行在一个单独的Leap Motion创建的无名线程上!

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

我已经尝试在Dispose()中调用CleanUp的东西(视图和演示者(当然不是多余的))并且这也不起作用 .

我承认我不是线程专家,但是我不知道这里是否有任何冲突,以及为什么RemoveListener从控制器线程工作,而不是从实际添加了监听器的主线程 . 任何帮助表示赞赏!

解决方案

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

1 回答

  • 0

    在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

相关问题