GeorgeF0
GeorgeF0

Reputation: 431

Get notified when a process stops responding (preferably C#)

I am wondering if there is a way to listen to an event in order to be notified whenever a particular process is not responding (not when it exits!).

This solution here allows to check whether a certain process is responding or not, but this solution can only be used with polling: Check status of process. It would be nice if I could "listen" to process.Responding in this solution.

As an example, I want to be listening to all Visual Studio processes on a windows machine and if any of them becomes unresponsive then I want to be notified so that I can act upon it accordingly. Many thanks in advance!

Upvotes: 2

Views: 1370

Answers (1)

user985916
user985916

Reputation:

Something like this could work. It's a bit of a primitive example that uses Tasks to poll Process.Responding and fire an event when it returns false. I don't think you'll be able to get around polling the process periodically, at least not in an easy/concise way.

Each Task will run in a background thread so as to not hang the main thread while it watches over each process.

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 );
        }
    }
}

Example usage:

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();
    }
}

Upvotes: 1

Related Questions