我一直有这个问题,解决它,然后当我实现新代码时,它又回来了。这让我发疯了!
我最终发现,如果您实例化任何类型的Window,即使您从未调用Show()或ShowDialog(),当您关闭应用程序时,它也不会终止。所以现在我确保在适当的时候调用Close(),并且问题永远不会出现在我创建的所有Windows中。
我已经实现了更多不会创建窗口的新功能(据我所知!),但现在我的应用程序不会再次终止 。我认为,在VS IDE中暂停是没用的,因为线程没有任何上下文,所以我无法弄清楚导致挂起的代码。
通常情况下,我希望在后台执行但未退出的线程(并且未设置为后台线程)会导致此行为,但此时我没有创建任何线程。
任何人都可以推荐一个好的工具(免费或需要许可证),这将有助于我快速解决这些愚蠢的问题吗?现在,我要回去,评论一大堆新代码,然后逐行取消注释直到问题重新出现。蛮力是我通常最终修复这些事情的方式,并且非常感谢让我的生活更轻松的工具。 :)
答案 0 :(得分:3)
听起来您可能遇到其他问题正在解决的后台线程的其他问题但是对于WPF Windows,您是否尝试更改App类的ShutdownMode?您还可以通过明确调用Shutdown来尝试强制退出应用程序:
Application.Current.Shutdown();
答案 1 :(得分:2)
如果使用托管代码和非托管代码进行附加,则可能会获得更多信息。在Visual Studio 2008中,您可以在“附加到进程”表单中更改模式。按“选择...”按钮并为“管理”和“本机”指定调试。
(在此之前,请确保您的符号路径已设置。转到工具/选项,调试,符号。在符号文件位置列表中输入http://msdl.microsoft.com/download/symbols。在某些目录中本地缓存符号。)
在托管和非托管模式下连接时,应该获得更大的调用堆栈。我建议右键单击Call Stack调试窗口并选择“Include Call to / From Other Threads”。
如果您的主线程显示System.Windows.Forms.Application.Run或ThreadContext.RunMessageLoop,那么您的UI线程的消息泵仍处于活动状态且仍然在传送消息。如果由于某种原因,它正在转换到另一个线程,那么它就无法退出直到它完成。
您还可以查看其余托管和非托管线程的完整堆栈跟踪。您可能希望查找垃圾收集器线程并查看它正在执行的操作。查找一个包含“GCHeap :: FinalizerThreadStart”的堆栈。这可能正在做点什么。
可能还有一个忙于尝试工作的GID +线程。
答案 2 :(得分:1)
我不是故意过度简化,但您是否尝试将对话窗口的所有者设置为MainWindow?当MainWindow关闭时,这将强制关闭对话窗口。换句话说,它看起来像这样:
dialog.Owner = Window.GetWindow(this);
// Or...
dialog.Owner = Application.Current.MainWindow;
这对你来说可能不是一个选择,但我只是想把它扔出去,因为你的帖子没有提到你不想设置窗口的所有者。
答案 3 :(得分:0)
虽然在您的特定情况下它可能没有用,但Process Explorer是查看正在运行的进程并查看有多少线程等的绝佳工具。