2014-10-28 60 views
1

我想知道是否有方法來監聽某個事件,以便在特定進程沒有響應時(而不是當它退出時)通知。當進程停止響應(最好是C#)時收到通知

此解決方案允許檢查某個進程是否正在響應,但此解決方案只能與輪詢一起使用:Check status of process。如果我可以在此解決方案中「傾聽」process.Responding,那將會很好。

作爲一個例子,我想要監聽Windows機器上的所有Visual Studio進程,如果其中任何一個變得沒有響應,那麼我希望得到通知,以便我可以相應地採取行動。提前謝謝了!

+0

有效聽力是輪詢的反向,則需要應用程序來在一個時間週期中發送的信號,並且你偵聽器,以將其標記爲不響應如果它不...呃? – 2014-10-28 14:35:02

+0

查看http://stackoverflow.com/questions/7024626/check-status-of-process-and-restart-process-if-unresponsive-stopped-python – 2014-10-28 14:37:00

+0

製作定期發送信號或心跳(等)的應用程序仍然是輪詢。我正在尋找一種純粹的面向事件的方式,因爲它將是一個實時應用程序,我不能每秒進行5次輪詢! :D我想知道Windows是否提供這樣的服務(在google上找不到任何東西) – 2014-10-28 14:48:01

回答

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(); 
    } 
} 
相關問題