C# 生成的进程的执行时间在数周后增加

C# 生成的进程的执行时间在数周后增加,c#,C#,当我使用System.Diagnostics.Process()创建进程时,我遇到了一个奇怪的问题,即增加执行时间。我有一个“父”控制台应用程序,它定期(每隔几秒钟)创建其他“子”控制台应用程序。子进程执行一些工作(需要几百毫秒)并退出。 在大约4-12周内,一切正常。然后,子进程的执行时间开始缓慢增加。几周后,执行时间增加了一倍或三倍,并且越来越多的子进程被父应用程序终止,父应用程序通过Process.WaitForExit(TimeOutValue) 我现在停止并重新启动“父”应用程序。之后

当我使用
System.Diagnostics.Process()
创建进程时,我遇到了一个奇怪的问题,即增加执行时间。我有一个“父”控制台应用程序,它定期(每隔几秒钟)创建其他“子”控制台应用程序。子进程执行一些工作(需要几百毫秒)并退出。
在大约4-12周内,一切正常。然后,子进程的执行时间开始缓慢增加。几周后,执行时间增加了一倍或三倍,并且越来越多的子进程被父应用程序终止,父应用程序通过
Process.WaitForExit(TimeOutValue)

我现在停止并重新启动“父”应用程序。之后,子进程的执行时间与开始时一样正常。
我监视了“父”应用程序的所有性能计数器。然而,没有增加的计数器。我无法理解“父”应用程序如何对“子”应用程序的执行时间产生如此大的影响。在下面的代码中,我去掉了不必要的部分来关注问题。有人知道这里出了什么问题吗?
操作系统是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());
            }
        }
    }
}

我已经在虚拟机(Win7 prof.64位、4Gb RAM、2.27Ghz的Xeon)上运行了上述示例。在运行大约4小时(大约88000个样本)后,我可以看到执行时间(从创建子进程的进程中可以看到)缓慢增加

但是,从子进程的角度来看,执行时间似乎没有改变:

然后,我将
System.diagnostics.Process()
的创建放在bassfader建议的using块中。我允许子进程在被父进程终止之前运行4000毫秒(而不是2000毫秒)。现在,执行时间开始增加大约需要30小时(这意味着大约550000个样本):

同样,从子进程中看到的执行时间似乎没有改变(我想上传这些图表,但我只允许在这里附加两张图片)


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

我已经在虚拟机(Win7 prof.64bit,4Gb RAM,2.27Ghz的Xeon)上运行了上述示例。在运行大约4小时(大约88000个样本)后,我可以看到执行时间(从创建子进程的进程中可以看到)缓慢增加

但是,从子进程的角度来看,执行时间似乎没有改变:

然后,我将
System.diagnostics.Process()
的创建放在bassfader建议的using块中。我允许子进程在被父进程终止之前运行4000毫秒(而不是2000毫秒)。现在,执行时间开始增加大约需要30小时(这意味着大约550000个样本):

同样,从子进程中看到的执行时间似乎没有改变(我想上传这些图表,但我只允许在这里附加两张图片)


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

我真的不知道这是否会导致此类问题,但我注意到您在使用后没有处理
System.Diagnostics.Process
。您是否尝试过简单地将其包装在
using
子句中以便正确处理?我不知道这是否会导致此类问题,但我注意到您在使用
系统.Diagnostics.Process
后没有处理它。您是否尝试过使用子句将它简单地包装在
中,以便正确地处理它?