进程停止响应时收到通知(最好是C#)

时间:2014-10-28 14:26:27

标签: c# windows process-monitoring

我想知道是否有办法监听某个事件,以便在特定进程没有响应时通知(而不是在它退出时!)。

此解决方案允许检查某个进程是否响应,但此解决方案只能用于轮询:Check status of process。如果我可以"听"那将是很好的。在此解决方案中process.Responding

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

1 个答案:

答案 0 :(得分:1)

这样的事情可行。这是一个使用Tasks来轮询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();
    }
}