3

在我使用 Ninject 重构我的 DI 项目之前,我有一个简单的测试类和一个简单的方法:

    public void TestImport()
    {
        var functionality = new ImportFunctionality();
        functionality.Execute();
    }

当我运行这个“应用程序”(只是一个用于集成测试我的库的沙盒 WPF 客户端应用程序)时,我显示了“主”窗口并单击该窗口上的一个称为此TestImport方法的按钮,该方法执行然后我可以测试和调试我的代码,然后当主窗口关闭时,应用程序就死在那里,VS 将退出调试模式。正常的东西。

然后我重构了整个事情,并在代码中使用 Ninject、工厂和接口实现了依赖注入;该TestImport方法现在看起来像这样:

    public void TestImport()
    {
        using (var kernel = new StandardKernel())
        {
            kernel.Load<SecurityNinjectModule>();
            kernel.Load<HelpersNinjectModule>();
            kernel.Load<ImportFunctionalityNinjectModule>();

            var functionality = kernel.Get<IImportFunctionality>();
            functionality.Execute();
        }
    }

现在,当我运行 WPF 沙盒/测试应用程序时,一切正常,这很好,除了“主”窗口关闭时,应用程序不再退出并且 Visual Studio 仍处于调试模式。我添加了调用以Dispose()希望修复它,但没有运气;将它包装在一个using块中也不能解决它。

如果我在没有单击按钮运行方法的情况下运行沙箱TestImport,然后关闭主窗口,应用程序将正常关闭。

这将我引向 Ninject 内核对象。Dispose()尽管有电话,它会以某种方式保留其资源吗?那么如何正确关闭运行 Ninject 3.0 的应用程序呢?

编辑 如果我打开调试/窗口/线程窗口,我会看到所有实例化的线程要么处于睡眠状态,要么“处于睡眠状态,等待或加入”,如果不是“不可用”;一个名为 的线程.NET System Events正在休眠、等待或加入;主线程是“管理到本机转换”以及一个名为的线程vshost.RunParkingWindow- 这就是我得到的地方为什么我的 WPF 应用程序在显示 WinForms 对话框后不能正确关闭?. 答案似乎可行,因为它被接受,但正如@BahriGungor 所说“使用 System.Environment.Exit 很像使用炸药制作门,因为你不想遵循出口标志”。它没有说明为什么会这样

有趣的是,它不会始终如一地发生:有时我可以中断并单步执行代码,当我“F5”恢复,然后关闭主窗口时,它确实会正常关闭。这是怎么回事?

编辑 2 该功能会显示一个FileDialog,如果该对话框未返回 Excel 工作簿的文件名,则不会显示导入窗口。我把它缩小到这个:

  • 如果显示导入视图,无论在关闭主应用程序窗口后如何关闭 VS 都会正确退出调试模式。
  • 如果导入视图未显示(即FileDialog不返回任何可编辑的内容),则 VS在关闭主应用程序窗口后不会退出调试模式。
4

1 回答 1

1

您的 DI 应该有一个组合根,其中 99% 的 DI 代码都在其中。工厂应该是依赖注入的 1%。对于WPF,即 onStartup 方法

此外,我在您的代码中没有看到您指定 DI 的生命周期管理部分的任何地方。如果您没有指定生命周期管理,Bind<Samurai>().ToSelf().InSingletonScope();那么您可能没有得到生命周期管理和处置。这是有关 ninject 范围的信息

你说你在途中添加了一个调用来处理某个地方,但是如果你设置了没有弱引用的事件侦听器,则可能会出现内存泄漏导致缺乏处理。

最后,您是否遵循链接System.Environment.Exit问题的其他答案? 检查调试器中的 Application.Current.Windows 集合以找到有问题的窗口。 https://stackoverflow.com/a/7349650/57883

您是否尝试过使用其他 win 表单对话框或仅使用一个来查看它是否可重现?

于 2013-05-06T12:39:36.583 回答