在我用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的应用程序?
修改
如果我打开debug / windows / threads窗口,我会看到所有实例化的线程都处于休眠或“处于休眠,等待或加入”状态,如果不是“不可用”;一个名为.NET System Events
的线程正在睡觉,等待或加入;主线程是“管理到本机转换”以及一个名为vshost.RunParkingWindow
的线程 - 这是我到达Why won't my WPF application close properly after it displays a WinForms dialog?的地方。答案似乎是有效的,因为它被接受,但正如@BahriGungor所说“使用System.Environment.Exit就像使用炸药来制作一扇门,因为你不想按照出口标志 ”。它并没有说为什么会发生这种情况。
有趣的是,它不会始终如一地发生:有时我可以打破并逐步执行代码,当我“F5”恢复,然后关闭主窗口时,它会正常关闭。发生了什么事?
编辑2
该功能会显示FileDialog
,如果该对话框未返回Excel工作簿的文件名,则导入窗口不会显示。我把它缩小到了这个范围:
FileDialog
未返回任何可编辑的内容),则在关闭主应用程序窗口后,VS 将不会退出调试模式。答案 0 :(得分:1)
您的DI应该有composition root,其中99%的DI代码存在。工厂应该是1%依赖注入的情况。对于WPF that is the onStartup method。
此外,我没有在您的代码中看到指定DI的生命周期管理部分的任何位置。如果您没有指定名为Bind<Samurai>().ToSelf().InSingletonScope();
的终身管理,那么您可能无法获得终身管理而无需处置。 Here's the information on scopes for ninject
你说你在路上的某个地方添加了一个调用处理,但是如果你设置的事件监听器没有弱引用,那么可能会a memory leak导致缺乏处置。
最后您是否按照关联System.Environment.Exit
问题的其他答案进行了操作?
检查调试器中的Application.Current.Windows集合以查找有问题的窗口。 https://stackoverflow.com/a/7349650/57883
您是否尝试过使用其他获胜表单对话框,或仅使用其他对话框来查看它是否可重现?