C#检测远程应用程序故障

C#检测远程应用程序故障,c#,wmi,C#,Wmi,有人知道检测远程应用程序是否失败/崩溃的方法吗?我的意思是当它变得不可用时——在这种情况下,你通常会在标题栏中看到“没有响应”——但关键是应用程序仍然在运行;因此,仅仅发现进程不再运行是不够的 WMI不支持在远程计算机上使用System.Diagnostics.Process.Responsing。。在Win32_进程中,似乎没有其他WMI属性可以查询此类信息。您可以使用轮询机制并定期询问远程应用程序的状态。很难知道应用程序是否已崩溃或是否正在执行有用的操作 考虑这一点: while(true

有人知道检测远程应用程序是否失败/崩溃的方法吗?我的意思是当它变得不可用时——在这种情况下,你通常会在标题栏中看到“没有响应”——但关键是应用程序仍然在运行;因此,仅仅发现进程不再运行是不够的


WMI不支持在远程计算机上使用System.Diagnostics.Process.Responsing。。在Win32_进程中,似乎没有其他WMI属性可以查询此类信息。

您可以使用轮询机制并定期询问远程应用程序的状态。

很难知道应用程序是否已崩溃或是否正在执行有用的操作

考虑这一点:

 while(true);
处理器(非常)忙。如果这是在一个单独的线程中完成的,它甚至可能会做出响应。然而,这确实是不必要的行为,因为应用程序不再工作了

解决这个问题的最佳方法是定期(在软件中的某些点上)添加某些计数器并广播这些计数器。一个看门狗应用程序可以监听这些广播,如果它们没有到达或不再有意义(计数器没有加起来),那么你可以终止进程并重新启动它

广播可以用多种方式进行。最简单的方法是只将计数器写入文件(确保在写入文件时锁定该文件,以便读取过程不会在完全相同的时间读取半个损坏的文件)


更高级的方法是使用命名管道,或使用套接字。UDP套接字在这种情况下非常容易设置和使用。不要担心“packetloss”,因为在本地网络上,这几乎从未发生过

在确定程序的“活跃度”时,重要的是测量该方面,以有用的方式定义它的活跃度

一些简单的“代理”方法表面上很吸引人,因为它们很简单,但从根本上说并不能衡量重要方面

可能最常见的是“进程是否处于活动状态”和“单独的心跳广播线程”,这可能是因为这样做非常简单:

bool keepSending = true; // set this to false to shut down the thread
var hb = new Thread(() => 
    {
         while (true)
             SendHeartbeatMessage();   
    }).Start();
然而,这两个都有一个严重的缺陷,如果应用程序中的实际工作线程被锁定(比如进入无限循环或死锁),那么您将继续愉快地发送OK消息。对于基于流程的监控,您将继续看到流程“活动”,尽管它不再执行真正的任务。
通过在主线程上分层测试进度,可以在许多方面改进线程一(显著增加复杂性和线程问题的机会),但这采用了错误的解决方案,并试图将其推向正确的解决方案

最好是将程序执行的任务作为活动性检查的一部分。可能是在每个子任务完成后直接从主线程进行心跳(有一个阈值以确保它不会经常发生),或者只是查看输出(如果存在)并确保输入产生输出

最好在内部(程序内部)和外部(特别是当程序有外部消费者/用户时)对此进行验证。如果您有web服务器:尝试使用它,如果您的应用程序是基于事件循环的系统:触发它必须响应的事件(并验证输出是否正确)。无论做什么,都要考虑到你希望确认有用和正确的行为发生,而不是仅仅是任何活动。

你越是验证程序的存在,以及它的操作,你的检查就越有用。您越远离内部状态,就会检查更多的系统,如果您在机箱上运行监视进程,则可能只检查本地环回,机箱外运行会验证更多的网络堆栈,包括经常被遗忘的方面,如DNS


不可避免地,这会使检查更难进行,因为您本质上考虑的是一项特定的任务,而不是一般的解决方案,因此,在许多情况下,这种方法的好处应该足以让您认真考虑。

非常感谢您的这一见解;非常有用。我认为这种方法最适合我的需要。