应用程序不会以0个线程退出

时间:2010-04-23 15:38:55

标签: c# winforms join multithreading termination

我们有一个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。这实际上导致应用程序锁定...它在Join完成后在UI线程上记录了几个调用,然后一切都停止了。如果设备断电,驱动程序永远不会启动,问题就会消失。因此看起来驱动程序必须负责保持应用程序的活动,即使它已经被关闭了。

3 个答案:

答案 0 :(得分:1)

创建线程时,请在它们上设置IsBackground = true。当您的主ui线程/应用程序关闭时,所有创建的线程将自动关闭。

http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

答案 1 :(得分:0)

您的Application.Run呼叫的子节点是否可能无法终止?此外,实际上导致应用程序退出的是什么 - 当所有线程都已终止时自动关闭(自动意味着您编写了一些代码来执行此操作),还是用户模仿?

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

答案 2 :(得分:0)

我们从未弄清楚根程序原因,但它是导致问题的特定驱动程序版本,并且升级到新驱动程序解决了问题。

不幸的是,如果其他人有一天遇到类似的问题,这就是我能给出的所有答案......