2016-09-21 61 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图片)

使用块似乎改善的情况。但是仍然存在资源损失。任何人都知道这里会发生什么,或者我可以在代码中做些什么来避免执行时间的增加?