检测应用程序何时停止响应,杀死并重新启动它

时间:2012-01-03 22:10:58

标签: c# windows

我正在开发一个高性能的应用程序,导致主进程看似停止响应和崩溃 - 不时 - 由于过载(我得到关闭应用程序对话框,以便应用程序永远不会退出本身,只是冻结,这很烦人)

我欢迎任何干净的方式以专业方式检测应用程序何时冻结,因此我可以使用BAT(或其他)自动杀死进程并重新启动。

当然,这是审核应用程序时的临时修复,但同时也非常方便。

TieBreaker: BTW,有没有办法覆盖Windows的异常屏幕,只是退出应用程序??? 这大部分时间都是令人讨厌的功能。

编辑:
上帝保佑:应用 IS 吓坏了,那么每一项任务都在BG工作人员和线程中运行!我在评论中指明了这一点。来吧,我不是那么傻。只是你的应用程序运行BG工作人员并不意味着它永远不会冻结!正如我所说,请务必回答我的问题,我不是在寻找有关如何设计我的应用程序的课程,我已经在努力了,我知道必须做些什么。正如多次指定的那样,我在此期间只需要修复服务器。 谢谢。

3 个答案:

答案 0 :(得分:11)

我会说,如果没有其他人会:)创建一个单独的表单应用程序 -

Process[] prs = Process.GetProcesses();

foreach (Process pr in prs)
{
    if (!pr.Responding) 
    {
        try
        {
            pr.Kill();
        }
        catch { }
    }
}

//then to restart-
var process = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = @"C:\yourapp.exe"
    }
};
process.Start();

显然过于简单。

答案 1 :(得分:1)

将所有CPU密集型任务移出GUI,并调用gui报告任何状态。

主应用永远不应冻结。我编写了一个应用程序,它生成了超过500个线程(一次全部)并管理它们,因为它们异步(.net 2)处理了多个数据库调用。我相信你需要系统地将所有进程移动到线程安全的情况并删除任何直接的GUI调用。

ADDENDUM我如何运行500多个线程:

  1. 从头开始在所有共享数据位置上使用智能锁。请参阅我的博客文章

    Smart Resource Locking in C# .Net for Thread Safe Code
    C# MultiThreading Using ThreadPool, Anonymous Delegates and Locks

  2. 创建的接口,指定了一个包含数据的操作操作,错误状态为属性。
  3. 为创建,启动和清理线程操作创建的线程类(对于#4和#5中的类)。 没有业务逻辑,只是在一个位置处理线程的方法。
  4. 基于#2中的接口创建的类,也来自步骤#3。通过接口的类需要获取数据并放置数据(通过本地化锁定线程安全)并报告其状态。如果没有通过thread.Sleep(0)完成任何工作而不忙于等待, Class也设计为放弃线程周期。
  5. 创建了Manager类(在自己的线程上运行并从#3派生)。它启动了1-N#4类来完成工作。这些实例中的每一个都被放入工作清单中。
  6. Manager类只是浏览了工作列表,其中列出了已完成工作的实例,如果已完成,则将实例移动到完成的工作。 Manager类还将状态记录(通过锁的线程安全)保存到公开的属性(以及子实例报告的任何错误)。经理在每次运行后都放弃了线程循环,并在再次启动之前睡了250毫秒。
  7. GUI线程有工作计时器,处理从经理获取特定状态。他们将从管理器的属性中提取数据并调用GUI来定位控制(gridview),该控件报告所有状态和错误。
  8. 通过这样做,我能够实现执行特定工作的单个线程,并且如果一个进程遇到它报告的问题,或者它报告成功或失败。这些消息冒泡到了管理器,它冒泡到了冒泡到GUI的定时器。除了启动管理员和计时器之外,gui没有处理任何业务逻辑。


    我知道这对你现在的情况没有帮助,而且我感觉到你的痛苦。但是,除非您能够从GUI中分离出业务逻辑并处理线程(后台工作者)中的错误情况并将其冒泡到GUI,否则您仍然会对当前代码感到沮丧。

    如果某些东西是锁定的,这表明业务逻辑与GUI操作紧密耦合,并且必须先离开,然后才能从GUI获得所需的性能。

    HTH

答案 2 :(得分:1)

我们通过让主服务exe只是一个启动子线程的shell来处理服务。

子线程负责报告回父线程,只要他们能够记录他们被“看到”的最后日期/时间。

在定期间隔内,服务应用程序会检查子进程列表,如果在预定的时间段(即2分钟)内没有看到,但没有报告它已关闭,则为进程将首先尝试加入线程并优雅地关闭它(通常是失败的)然后,如果这不起作用,则中止线程。

我们已成功使用此方法多年,从我们运行的OCR服务因OCR软件中的错误而不断挂起时开始。