2017-02-16 11 views
0

CPU使用率を監視し続けるスレッドがWindowsサービスに必要です(たぶん5秒ごと)。 CPU使用率が低い場合は、他のスレッドをアクティブにする必要があります。CPU使用率のスレッドを継続的に監視する

私はこのSO QuestionからのサンプルCPU使用率監視コードを見つけました。これはコンソールアプリケーションのコードで、Timerを生きたままにしておくと、人は最後にConsole.ReadLine();を使用しています。

CPU使用率コンソールアプリケーション:

using System; 
using System.Diagnostics; 
using System.Timers; 
using System.Threading; 
using System.Collections.Generic; 

namespace CPUPerformanceMonitor 
{ 
    class MonitoringApplication 
    { 
     protected static PerformanceCounter cpuCounter; 
     protected static PerformanceCounter ramCounter; 

     public static void TimerElapsed(object source, ElapsedEventArgs e) 
     { 
      float cpu = cpuCounter.NextValue(); 
      float ram = ramCounter.NextValue(); 
      Console.WriteLine(string.Format("CPU Value: {0}, ram value: {1}", cpu, ram)); 
     } 

     public static void Main() 
     { 
      cpuCounter = new PerformanceCounter(); 
      cpuCounter.CategoryName = "Processor"; 
      cpuCounter.CounterName = "% Processor Time"; 
      cpuCounter.InstanceName = "_Total"; 

      ramCounter = new PerformanceCounter("Memory", "Available MBytes"); 

      try 
      { 
       System.Timers.Timer t = new System.Timers.Timer(1200); 
       t.Elapsed += new ElapsedEventHandler(TimerElapsed); 
       t.Start(); 
       Thread.Sleep(10000); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("catched exception"); 
      } 

      while (true) //Another sample BAD way to keep the timer alive 
      { } 

      //Console.ReadLine(); //just to keep the time alive 
     } 
    } 
} 

問題:どのように私は、Windowsサービスアプリケーションでそれを実装します。つまり、どうやってスレッドを生かし続けるのか。

私のWindowsサービスの構造:

私はスレッドのコールバックメソッドOnStart()を呼び出します。このスレッドコールバックメソッドは、CPUMonitorTimerのコードを含む)のStartCPUMonitorinig()メソッドを呼び出します。あなたはどこで、どのように出力パフォーマンスデータにしたいですか検討する必要がありServiceタイプにこれを実装するに

public void CPUMonitorinigThreadCallback() 
    { 
     //If nothing is there in this function, the thread will start up and then immediately shutdown. To deal with this situation, use "_shutdownEvent" 
     //The while loop checks the ManualResetEvent to see if it is "set" or not. 
     while (!_shutdownEvent.WaitOne(0)) 
     { 
      // Replace the Sleep() call with the work you need to do 
      //Sleep(1000); 
      objCPUMonitor.StartCPUMonitorinig(); 
     } 

    } 
+3

あなたはこれが間違った方法に近づいていると思います。基本的には、CPU使用率が低い場合に限り、いくつかの作業を完了しようとしているようです。ワーカースレッド(バックグラウンド、アイドルなど)の優先度を単純に下げることができると考えましたか?私があなたの意図を誤解した場合、あなたが達成しようとしているもの(一般的には)の広範なイメージを私に与えることができますか? –

+0

なぜスレッドが必要ですか?タイマーを使って5秒ごとに発砲することができます。 – CodeWeed

+0

Windowsサービススレッドはスリープ状態にはなりません。あなたは基本的に何もする必要はありません、それは生き続けるでしょう、あなたがイベントに登録する限り、彼らは育てられます\ – zaitsman

答えて

0

。 Windowsサービスを使用する別のアプリケーションやオーバーレイを作成し、サービスがその更新を終了するたびにこれらの値を表示することをお勧めします。あなたの後に今

public class MeService : ServiceBase 
{ 
    // for the ability to redirect stream 
    [DllImport("Kernel32.dll", SetLastError = true) ] 
    public static extern int SetStdHandle(int device, IntPtr handle); 

    // entry point 
    public static void Main(string[] args) 
    { 
     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] 
     { 
      new MeService() 
     }; 
     ServiceBase.Run(ServicesToRun); 
    } 

    PerformanceObject pObject; // object to retrieve and return performance status 
    IContainer components; 
    FileStream fStream; 
    public MeService() 
     : base() 
    { 
     components = new Container(); // initialize components holder 
     ServiceName = "MeService"; // set your service name 
    } 

    // Here check for custom commands on your service 
    protected override void OnCustomCommand(int command) 
    { 
     if(command == 1) 
     { 
      // redirect stream 
      fStream = new FileStream("<path_to_your_out_file>", <FileMode.Here>, <FileAccess.Here>); 
      IntPtr streamHandle = fStream.Handle; 
      SetStdHandle(-11, handle); // DWORD -11 == STD OUT 
     } 
     else if(command == 1337 && pObject != null) // example command 
     { 
      // write string.Format("CPU Value: {0}, ram value: {1}", cpu, ram); 
      // into your service's std out 
      Console.WriteLine(pObject.GetPerformance()); 
     } 
     base.OnCustomCommand(command); 
    } 

    // whenever service starts create a fresh performance counter object 
    protected override void OnStart(string[] args) // will be called when service starts 
    { 
     pObject = new PerformanceObject(); 
    } 

    // called whenever service is stopped 
    protected override void OnStop() 
    { 
     // remove performance counter object 
     pObject.Dispose(); 
     pObject = null; 
    } 

    protected override void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (components != null) 
      { 
       components.Dispose(); 
      } 

      if (pObject != null) 
      { 
       pObject.Dispose(); 
      } 
     } 
     base.Dispose(disposing); 
    } 
} 

:これは、共有メモリ、ファイル、データベース、Windowsメッセージポンプを使用して行うことができ、サービスオブジェクトを作ることによって、あなたが実際にあなたのサービスを作り始めることができ、これらの事を考慮するなど

アウトはstdあなたはあなたの "ディスプレイ"アプリケーションを作成することができます。これは、サービスのstdを自分自身のリーダーにリダイレクトして、そのストリームから読むことができるようにする必要があります。

class Program 
{ 
    static void Main(string[] args) 
    { 
     FileStream fileStream = new FileStream("<PATH_TO_THE_SAME_FILE_AS_SERVICE>", <FileMode.Here>, <FileAccess.Here>); 
     // create service controller that will control "MeService" service 
     ServiceController Controller = new ServiceController("MeService"); 
     if (Controller.Status == ServiceControllerStatus.Stopped) 
     { 
      Controller.Start(); 
     } 

     while (Controller.Status != ServiceControllerStatus.Running) 
     ; 

     Controller.ExecuteCommand(1); // redirect the stream.   

     string command = string.Empty; 
     while((command = Console.ReadLine()) != "exit") 
     { 
      if(command == "refresh") 
      { 
       if (Controller.Status == ServiceControllerStatus.Running) 
       { 
        Controller.ExecuteCommand(1337); 
        string performance = fileStream.ReadLine(); 
        Console.WriteLine(performance); 
       } 
      } 
     } 
    } 
} 

今あなたがしなければならないすべてはあなたのサービスでファイルをインストールして、あなたが既に持っているが、あなたはそれを上記のスニペットで使用するビットを変更する必要があります縫い目たPerformanceObjectを作成作成することです。

関連する問題