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