我们有一个 WinForms 桌面应用程序,它是多线程的。3 个线程与 Application.Run 和一堆其他后台工作线程一起运行。让所有线程正确关闭有点棘手,但我想我终于做对了。
但是当我们实际部署应用程序时,用户开始体验到应用程序不退出。有一个 System.Threading.Mutex 可以防止他们多次运行应用程序,因此他们必须进入任务管理器并杀死旧的,然后才能再次运行它。
在主线程退出之前,每个线程都会获得一个 Thread.Join,并且我将日志记录添加到我生成的每个线程中。根据日志,每一个启动的单线程也退出,主线程也退出。更奇怪的是,运行 SysInternals ProcessExplorer 显示应用程序退出时所有线程都消失了。如,有 0 个线程(托管或非托管),但进程仍在运行。
我无法在任何开发人员的计算机或我们的测试环境中重现这种情况,到目前为止,我只在 Windows XP(不是 Vista 或 Windows 7 或任何 Windows Server)上看到过这种情况。一个进程如何以 0 个线程继续运行?
编辑:
这里有更多细节。事件循环之一是托管 Win32 互操作 DLL,它使用 COM 对象与设备驱动程序对话。我将它放在自己的线程中,因为设备驱动程序对时间敏感,并且每当 UI 线程会阻塞很长时间(例如等待数据库调用完成)时,它都会干扰设备驱动程序。
所以我更改了代码,因此主线程将使用设备驱动程序线程执行 Thread.Join。这实际上导致应用程序锁定......它在加入完成后在 UI 线程上记录了更多调用,然后一切都停止了。如果设备断电,驱动程序永远不会启动,问题就会消失。所以看起来驱动程序必须负责保持应用程序的活动,即使在它应该被关闭之后也是如此。