代码之家  ›  专栏  ›  技术社区  ›  Bryce Wagner

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

  •  2
  • Bryce Wagner  · 技术社区  · 14 年前

    我们有一个WinForms桌面应用程序,它是多线程的。3个线程与应用程序一起运行。运行和一堆其他后台工作线程。让所有线程正常关闭有点棘手,但我认为我终于弄好了。

    但当我们实际部署应用程序时,用户开始体验到应用程序没有退出。有一个system.threading.mutex防止他们多次运行应用程序,所以他们必须进入任务管理器并杀死旧的应用程序,然后才能再次运行它。

    每一个线程都有一个线程。在主线程退出之前联接,然后将日志记录添加到生成的每个线程。根据日志,每个启动的线程也会退出,主线程也会退出。更奇怪的是,运行SysInternals ProcessExplorer会在应用程序退出时显示所有线程都消失。与中一样,有0个线程(托管或非托管),但进程仍在运行。

    我无法在任何开发人员的计算机上或我们的测试环境中重现这一点,到目前为止,我只看到它发生在Windows XP上(不是Vista、Windows7或任何Windows服务器)。进程如何在0线程的情况下继续运行?

    编辑:

    这里更详细一点。事件循环之一是托管一个win32 interop dll,该dll使用COM对象与设备驱动程序通信。我把它放在自己的线程中,因为设备驱动程序是时间敏感的,并且每当UI线程阻塞大量时间(例如等待数据库调用完成)时,它都会干扰设备驱动程序。

    所以我修改了代码,让主线程执行一个线程。与设备驱动程序线程联接。这实际上导致应用程序锁定…在连接完成后,它在UI线程上记录了更多的调用,然后一切都停止了。如果设备断电,驱动程序就不会启动,问题就消失了。所以看起来驱动程序必须负责保持应用程序的活动状态,即使在应用程序被假定关闭之后也是如此。

    3 回复  |  直到 14 年前
        1
  •  1
  •   David    14 年前

    创建线程时,在线程上设置isbackground=true。当主UI线程/应用程序关闭时,所有创建的线程将自动关闭。

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

        2
  •  0
  •   SqlRyan    14 年前

    是否有可能应用程序的子级。运行调用不会终止?另外,是什么导致应用程序退出——当所有线程都终止时,它是否自动关闭(自动意味着您编写了一些代码来完成这个操作),或者它是用户模仿的?

    我曾经遇到过一个问题,在我的“线程完成”事件代码中有一个争用条件,有时会导致您看到什么。最后两个线程将同时完成,同时激发事件,并且每个事件都将决定它不是最后一个线程,因此应用程序将继续运行,即使线程计数为零。为了解决这个问题,我可以找到并消除争用条件,但是您也可以使用一个计时器,它每隔一两秒钟检查一次,获取线程的计数,如果没有线程仍然打开,它就会终止应用程序。

        3
  •  0
  •   Bryce Wagner    14 年前

    我们从来没有找出根本的编程原因,但是是一个特定的驱动程序版本导致了这个问题,升级到一个新的驱动程序修复了这个问题。

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