无限循环中的 WinForm C# “新进程”导致应用程序崩溃

本文关键字:新进程 崩溃 应用程序 进程 WinForm 无限循环 | 更新日期: 2023-09-27 18:37:01

我有一个要求,我需要我的代码块无限运行(退出是基于按钮单击的中断)。

在每次迭代中,我都会创建一个进程,启动它,操作输出,然后释放进程。

    void status()
    {
        do{
            Process test1 = new Process();
            test1.StartInfo.FileName = "doSomething"; // doSomething is executable
            test1.StartInfo.UseShellExecute = false;
            test1.StartInfo.CreateNoWindow = true;
            test1.StartInfo.RedirectStandardOutput = true;
            test1.StartInfo.RedirectStandardError = true;
            test1.Start();
            string output = test1.StandardOutput.ReadToEnd();
            test1.WaitForExit();
            if (Regex.IsMatch(output, "DEVICE_READY", RegexOptions.IgnoreCase))
            {
                pictureBox2.BackColor = Color.Green;
            }
            else
            {
                pictureBox2.BackColor = Color.Yellow;
            }
            test1.Dispose();        
        }while(true);    
    }

问题是应用程序使用此代码崩溃。如果我只是删除循环,它工作正常。

我在调试时检查了一下,应用程序的内存使用量随着循环的每次迭代而不断增加,使应用程序在某一点崩溃。

我理解的是Dispose()将释放所有资源...因此,内存不应随着每次迭代而增加。

有人可以帮助了解导致内存使用量增加的原因吗?

无限循环中的 WinForm C# “新进程”导致应用程序崩溃

当我必须处理饥饿的进程(例如图片操作)时,我要做的是显式调用垃圾收集器。

这不是最干净的方式(成本很高),但合理使用,它可以解决问题。

void status()
{
    // will be used to explicitly call the garbage collector
    const int COLLECT_EVERY_X_ITERATION = 10;
    // store the current loop number
    int currentIterationCount = 0;
    do
    {
        // increase current iteration count
        currentIterationCount++;
        using (Process test1 = new Process())
        {
            test1.StartInfo.FileName = "doSomething"; // doSomething is executable
            test1.StartInfo.UseShellExecute = false;
            test1.StartInfo.CreateNoWindow = true;
            test1.StartInfo.RedirectStandardOutput = true;
            test1.StartInfo.RedirectStandardError = true;
            test1.Start();
            string output = test1.StandardOutput.ReadToEnd();
            test1.WaitForExit();
            if (Regex.IsMatch(output, "DEVICE_READY", RegexOptions.IgnoreCase))
            {
                pictureBox2.BackColor = Color.Green;
            }
            else
            {
                pictureBox2.BackColor = Color.Yellow;
            }
        }
        // Explicitly call garbage collection every 10 iterations
        if (currentIterationCount % COLLECT_EVERY_X_ITERATION == 0)
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
    } while (true);
}