2016-09-21 60 views
1

我在創建具有System.Diagnostics.Process()的進程時增加執行時間有一個好奇的問題。我有一個「父」控制檯應用程序,它定期(每隔幾秒)創建其他「子」控制檯應用程序。子進程執行一些工作(需要幾百毫秒)並退出。
一切正常運行約4-12周。然後,子進程的執行時間開始緩慢增加。幾周後,執行時間增加了一倍或三倍,並且越來越多的子進程被父應用程序殺死,該應用程序通過Process.WaitForExit(TimeOutValue)監視子執行時間。
我現在停止並重新啓動「父」應用程序。之後,子進程的執行時間與開始時一樣正常。
我監視了「父」應用程序的所有性能計數器。但是沒有增加的櫃檯。我無法理解「父」應用程序如何對「子」應用程序的執行時間產生這樣的影響。在下面的代碼中,我已經剝去了不必要的部分來關注問題。有誰知道這裏出了什麼問題?
OS爲Windows Server 2008 R2標準幾星期後產卵過程的執行時間增加

應用:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Diagnostics; 
using System.IO; 

namespace Bss.CheckExecTimeScheduler 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string Arg0 = "Bss.CheckTask.exe"; 
      string Args = ""; 
      int WaitForExit = 2000; 

      int NumOfTimeOuts = 0; 
      int NumOfNormalExits = 0; 
      int NumOfExceptions = 0; 
      long MinExecTime = 100000; 
      long MaxExecTime = 0; 

      Console.WriteLine("Press 'r' for a report ..."); 
      Console.WriteLine("Press 's' to start/stop execution ..."); 
      Console.WriteLine("Press 'q' to quit ..."); 
      Console.WriteLine(""); 

      while (true) 
      { 
       if (Console.KeyAvailable) 
       { 
        ConsoleKeyInfo cki; 

        cki = Console.ReadKey(); 

        if (cki.KeyChar == 'q') 
        { 
         return; 
        } 
        if (cki.KeyChar == 'r') 
        { 
         Console.WriteLine(""); 
         Console.WriteLine("Normal Exits: " + NumOfNormalExits.ToString()); 
         Console.WriteLine("Timeouts : " + NumOfTimeOuts.ToString()); 
         Console.WriteLine("Exceptions : " + NumOfExceptions.ToString()); 
         Console.WriteLine("Minimum execution time [ms]: " + MinExecTime.ToString()); 
         Console.WriteLine("Maximum execution time [ms]: " + MaxExecTime.ToString()); 
        } 
        if (cki.KeyChar == 's') 
        { 
         Console.WriteLine("Execution stopped. Press 's' to resume..."); 
         while (true) 
         { 
          cki = Console.ReadKey(); 
          if (cki.KeyChar == 's') 
          { 
           Console.WriteLine("Execution resumed..."); 
           break; 
          } 
          else 
          { 
           Console.WriteLine("Illegal key. Execution stopped. Press 's' to resume..."); 
          } 
         } 
        } 
       } 

       Stopwatch stopwatch = Stopwatch.StartNew(); 
       try 
       { 
        System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(Arg0, Args); 
        procStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
        System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
        proc.StartInfo = procStartInfo; 
        proc.Start(); 
        //AddMsg("Message: Command Thread launched. Arg0 = " + Arg0 + "; Args = " + Args + "; ProcessId = " + proc.Id.ToString()); 

        if (proc.WaitForExit(WaitForExit) == false) 
        { 
         if (!proc.HasExited) 
         { 
          proc.Kill(); 
          NumOfTimeOuts++; 
          AddExecTime("-1"); 
         } 
         else 
         { 
          long elapsed = stopwatch.ElapsedMilliseconds; 
          NumOfNormalExits++; 
          if (elapsed < MinExecTime) MinExecTime = elapsed; 
          if (elapsed > MaxExecTime) MaxExecTime = elapsed; 
          AddExecTime(elapsed.ToString()); 
         } 
        } 
        else 
        { 
         long elapsed = stopwatch.ElapsedMilliseconds; 
         NumOfNormalExits++; 
         if (elapsed < MinExecTime) MinExecTime = elapsed; 
         if (elapsed > MaxExecTime) MaxExecTime = elapsed; 
         AddExecTime(elapsed.ToString()); 
        } 
       } 
       catch (Exception ex) 
       { 
        NumOfExceptions++; 
        AddMsg("Exception catched: " + ex.Message); 
       } 
      } 
     } 

     public static void AddExecTime(string msg) 
     { 
      try 
      { 
       StreamWriter streamWriter = File.AppendText(DateTime.Now.ToString("yyyy.MM.dd") + "Bss.CheckExecTimeScheduler.ExecTimes.txt"); 
       streamWriter.WriteLine(msg); 
       streamWriter.Close(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error writing ExecTimes: Exception catched: " + e.ToString()); 
       Console.WriteLine(DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff ") + msg); 
      } 
     } 

     public static void AddMsg(string msg) 
     { 
      try 
      { 
       StreamWriter streamWriter = File.AppendText(DateTime.Now.ToString("yyyy.MM.dd") + "Bss.CheckExecTimeScheduler.Logfile.txt"); 
       streamWriter.WriteLine(DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff ") + msg); 
       streamWriter.Close(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error writing logfile: Exception catched: " + e.ToString()); 
       Console.WriteLine(DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff ") + msg); 
      } 
     } 
    } 
} 

兒童應用:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Diagnostics; 
using System.IO; 

namespace Bss.CheckTask 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Stopwatch stopwatch = Stopwatch.StartNew(); 

      Console.WriteLine("Hello World"); 

      long elapsed = stopwatch.ElapsedMilliseconds; 

      try 
      { 
       StreamWriter streamWriter = File.AppendText(DateTime.Now.ToString("yyyy.MM.dd") + "Bss.CheckTask.ExecTimes.txt"); 
       streamWriter.WriteLine(elapsed.ToString()); 
       streamWriter.Close(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error writing Bss.CheckTask.ExecTimes.txt: Exception catched: " + e.ToString()); 
      } 
     } 
    } 
} 
+0

我真的不知道這是否會導致此類問題,但我注意到,在您使用它之後,您沒有配置'System.Diagnostics.Process'。你是否試圖簡單地將它包裝在'using'子句中,以便妥善處理? – bassfader

回答

0

我已經運行在虛擬機上上面的例子(Win7的64位,4Gb RAM,Xeon 2.27Ghz)。大約4小時後(這是大約88000個樣本)運行後,我可以看到執行時間(從創建子進程的進程中看到的)增長緩慢。

Execution time chart parent view without using block

但是從子進程的視圖執行時間似乎並沒有改變:

我再封閉的System.Diagnotics.Process()創建一個使用塊所提議的bassfader。我允許子進程在父進程終止之前運行4000ms(而不是2000ms)。現在只需要30小時左右(這意味着約55萬樣本),直到執行時間開始增加:

Execution time chart parent view with using block

再次從子進程看到的執行時間似乎並沒有改變(我想上傳這些圖表,但我只允許在這裏附加2圖片)

使用塊似乎改善的情況。但是仍然存在資源損失。任何人都知道這裏會發生什麼,或者我可以在代碼中做些什麼來避免執行時間的增加?