【问题标题】:Get notified when a process stops responding (preferably C#)当进程停止响应时得到通知(最好是 C#)
【发布时间】:2014-10-28 23:35:49
【问题描述】:

我想知道是否有一种方法可以监听事件,以便在特定进程没有响应时(而不是在它退出时!)时得到通知。

这里的解决方案允许检查某个进程是否响应,但这个解决方案只能与轮询一起使用:Check status of process。如果我能在这个解决方案中“倾听”process.Responding,那就太好了。

例如,我想监听 Windows 机器上的所有 Visual Studio 进程,如果其中任何一个进程没有响应,那么我希望得到通知,以便我可以相应地采取行动。非常感谢!

【问题讨论】:

  • 监听实际上是轮询的反向,你需要应用程序在某个时间段发送一个信号,如果它没有,你监听器将它标记为没有响应......嗯?跨度>
  • 制作一个定期发送信号或心跳(等)的应用程序仍在轮询。我正在寻找一种纯粹面向事件的方式,因为它将是一个实时应用程序,而且我无法连续几天每秒轮询 5 次! :D 我想知道 Windows 是否提供这样的服务(在 google 上找不到任何东西)
  • 没有通知。 Microsoft 升级工程师有一个blog post,它演示了一种技术。他使用常用技术 SendMessageTimeout() 进行轮询。 IsHungAppWindow() 值得注意,但它带有到期通知。

标签: c# windows process-monitoring


【解决方案1】:

这样的事情可能会奏效。这是一个简单的例子,它使用任务来轮询Process.Responding,并在它返回 false 时触发一个事件。我认为您无法绕过定期轮询该过程,至少不能以简单/简洁的方式。

每个Task 都会在后台线程中运行,以免主线程在监视每个进程时挂起。

using System.Threading.Tasks;

namespace System.Diagnostics
{
    public class ProcessEventArgs : EventArgs
    {
        public Process Process { get; protected set; }

        public ProcessEventArgs( Process process )
        {
            this.Process = process;
        }
    }

    public delegate void ProcessNotRespondingEvent( object sender, ProcessEventArgs e );

    public class ProcessMonitor
    {
        public event ProcessNotRespondingEvent NotResponding;

        protected Process mProcess;

        public ProcessMonitor( Process process )
        {
            this.mProcess = process;
        }

        public async void Start()
        {
            Task t = null;
            t = Task.Run( () =>
            {
                while( this.mProcess.Responding )
                    t.Wait( 1000 ); //1 second

                this.OnNotResponding();
            } );

            await t;
        }

        protected void OnNotResponding()
        {
            if( this.NotResponding == null )
                return;

            ProcessEventArgs e = new ProcessEventArgs( this.mProcess );
            this.NotResponding( this, e );
        }
    }
}

使用示例

using System.Linq;

internal static class Program
{
    private static void Main()
    {
        var processes = Process.GetProcessesByName( "devenv" );
        var monitors = processes.Select( p => {
            var monitor = new ProcessMonitor( p );
            monitor.NotResponding += ( s, e ) => {
                Console.WriteLine( "Process {0}(pid: {1}) has stopped responding.", e.Process.ProcessName, e.Process.Id );
            };

            return monitor;
        } );

        foreach( var monitor in monitors )
            monitor.Start();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多