2010-04-23 23 views
2

我们有一个WinForms桌面应用程序,该应用程序非常多线程。 3个线程运行Application.Run和一堆其他后台工作线程。让所有线程正常关闭有点棘手,但我认为我终于明白了。应用程序不以0线程退出

但是,当我们实际部署应用程序时,用户开始体验应用程序不退出。有一个System.Threading.Mutex来防止他们多次运行应用程序,所以他们必须在任务管理器中杀死旧的应用程序,然后再运行它。

每个线程在主线程退出之前都会获得一个Thread.Join,并且将记录添加到我生成的每个线程。根据日志,每一个启动的线程也会退出,主线程也会退出。更奇怪的是,运行SysInternals ProcessExplorer显示所有线程在应用程序退出时消失。如在中,有0个线程(托管或非托管),但该进程仍在运行。

我无法在任何开发人员计算机或我们的测试环境中重现此操作,到目前为止,我只看到它在Windows XP(不是Vista或Windows 7或任何Windows Server)上发生。一个进程如何继续使用0个线程运行?

编辑:

这里有一些细节。事件循环之一是托管一个Win32 interop DLL,它使用COM对象与设备驱动程序对话。我把它放在它自己的线程中,因为设备驱动程序是时间敏感的,并且无论何时UI线程会阻塞很长时间(例如等待数据库调用完成),它都会干扰设备驱动程序。

因此,我更改了代码,以便主线程可以使用设备驱动程序线程执行Thread.Join。这实际上导致应用程序锁定......在Join完成后,它会在UI线程上记录更多的调用,然后一切都会停止。如果设备断电,驱动程序不会启动,问题就会消失。所以它看起来像驱动程序必须负责保持应用程序的活着,即使它被认为已被关闭。

+0

检查:HTTP://blogs.msdn。com/oldnewthing/archive/2004/07/23/192531.aspx – 2010-04-23 15:52:35

+0

这是一个有趣的场景,但与所发生的事情不匹配。该过程完全由用户通过任务管理器完成,它永远不会自行终止。我们让它运行了半小时。 – 2010-04-23 16:01:11

+0

你为什么确定只有0个线程?你用调试器测试过了吗?即使Windows XP任务管理器也可以向您显示线程数(但您应该通过菜单>查看>选择列将此列显式添加到进程选项卡中)。我怀疑实际上没有线程。我的第一个想法是在退出/清理过程中出现一些死锁。 – SergGr 2010-04-23 16:23:44

回答

0

我们也没搞清楚,根本原因程序,但它是导致此问题,升级到固定问题的新的驱动程序特定的驱动程序版本。

不幸的是,这是所有的答案,我可以给,如果别人有一天运行到类似的问题...

0

您的Application.Run调用的子程序可能没有终止吗?另外,实际上导致应用程序退出的是什么 - 它是否在所有线程终止时自动关闭(自动意味着您编写了一些代码来执行此操作),还是用户模仿?

我有一个问题,在我的“线程完成”事件代码中存在竞争条件时,有时会导致你所看到的情况。最后两个线程会同时完成,同时触发事件,并且每个事件都会决定它不是最后一个线程,所以应用程序将继续运行,即使线程数为零。为了解决这个问题,我能够找到并消除竞态条件,但是你也可以使用一个定时器来检查每一秒钟或两秒钟,得到一个线程的计数,如果没有打开,它会杀死应用程序。

+0

Application.Run调用由主线程上的Application.Exit()终止。我将尝试关闭其他Application.Run()调用,然后让主线程退出。 – 2010-04-23 16:10:14