2016-09-21 2 views
1

System.Diagnostics.Process()으로 프로세스를 생성 할 때 실행 시간이 늘어나는 데 궁금한 점이 있습니다. 나는 정기적으로 (몇 초마다) 다른 "자식"콘솔 응용 프로그램을 만드는 "부모"콘솔 응용 프로그램을 가지고 있습니다. 하위 프로세스는 몇 백 밀리 초가 걸리는 작업을 수행하고 종료합니다.
모든 것이 약 4-12 주 동안 잘 실행됩니다. 그런 다음 하위 프로세스의 실행 시간이 천천히 증가하기 시작합니다. 몇 주 후 실행 시간이 두 배 또는 세 배로 증가했으며 자식 프로세스가 자식 실행 시간을 모니터하는 부모 응용 프로그램에 의해으로 점점 더 자주 중단되었습니다.
이제 "상위"응용 프로그램을 중지했다가 다시 시작합니다. 그 후, 자식 프로세스의 실행 시간은 처음에는 정상입니다.
"상위"응용 프로그램의 모든 성능 카운터를 모니터링했습니다. 그러나 증가하는 카운터가 없습니다. 나는 "부모"응용 프로그램이 "자식"응용 프로그램의 실행 시간에 어떻게 영향을 미칠 수 있는지 이해할 수 없습니다. 아래의 코드에서 문제에 집중하기 위해 불필요한 부분을 제거했습니다. 누구가 여기에서 틀리게되고 있는지 아이디어가 있는가?
OS는 윈도우 서버 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, 제온 2.27Ghz). 약 4 시간 (약 88000 개의 샘플)을 실행하면 실행 시간 (하위 프로세스를 생성하는 프로세스에서 볼 수 있음)이 천천히 증가한다는 것을 알 수 있습니다.

Execution time chart parent view without using block

그러나 자식 프로세스의보기에서 실행 시간은 변경하지 않는 것 같다 bassfader 제안한

난 다음 사용하여 블록에 System.Diagnotics.Process()의 생성을 동봉. 부모 프로세스에 의해 종료되기 전에 자식 프로세스가 4000ms (2000ms가 아닌)를 실행하도록 허용했습니다. 실행 시간이 증가하기 시작할 때까지 지금은 약 30 시간 (이 약 550,000 샘플을 의미한다)을 취

Execution time chart parent view with using block

다시 자식 프로세스에서 본 실행 시간은 변경하지 않는 것 같다 (나는이 업로드하고 싶어 차트는 여기에 2 개의 그림 만 추가 할 수 있습니다)

사용하는 블록이 상황을 개선하는 것으로 보입니다. 그러나 여전히 자원이 손실됩니다. 아무도 여기에 무슨 일이 일어나는지 또는 실행 시간이 늘어나는 것을 피하기 위해 코드에서 할 수있는 일을 생각해보십시오.

관련 문제