【问题标题】:Handling Memory Limit on a Process in C#在 C# 中处理进程的内存限制
【发布时间】:2024-04-20 19:05:02
【问题描述】:

我有一个主应用程序通过 Process 组件调用另一个控制台应用程序。我通过自定义实现作业对象(代码中的类名称为“作业”)在控制台应用程序上设置了内存限制

每当超过内存限制时,就会引发 OutofMemory 异常或发生 KERNELBASE.DLL 故障。但我无法在主应用程序或控制台应用程序中捕获此异常。

如何处理?

无法在控制台应用程序中处理全局异常。

主应用程序有以下代码

private void startProcess()
    {
        try
        {                              
            Process proc = new Process();
            proc.StartInfo.FileName = @"E:\App\console.exe";            
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.UseShellExecute = false;
            proc.OutputDataReceived += Proc_OutputDataReceived;
            proc.ErrorDataReceived += Proc_ErrorDataReceived;
            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.Start();              
            Job job = new Job(_maxmemory);//memory limit set for child process
            job.AddProcess(proc.Id);//for the above console
            proc.WaitForExit();//this is called on a thread.         

        }
        catch (Exception ex)
        {
        }
    }

控制台应用有以下代码

static void Main(string[] args)
  {
            System.AppDomain.CurrentDomain.UnhandledException += CatchUnhandledException;
  }
static void CatchUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Console.Error.WriteLine(e.ExceptionObject.ToString());

        }

如何在主应用程序或控制台中处理此内存限制异常?

【问题讨论】:

  • 这是 Job 类 .NET 类型吗?我在 .NET 框架中找不到与您想要的行为相匹配的同名类。
  • @PMF c# Job 这是 Job Objects 的自定义实现,它需要最大内存限制以用于子进程。
  • 以前没见过,你说的是这个吗? docs.microsoft.com/en-us/windows/win32/procthread/job-objects
  • @ScottChamberlain 是的,您分享的链接。

标签: c# process memory-limit


【解决方案1】:

您的主应用代码显然不会捕获该错误。 Process.Start() 异步启动另一个进程,因此该方法将在另一个进程真正做某事之前结束。如果您想等待子进程终止,您必须致电proc.WaitForExit()。之后,您可以使用ExitCode 属性来查看您的子进程是否有错误。如果您的进程因异常而死亡,则该值将非零。

child 进程中这样的代码应该可以正常工作:

static void Main(string[] args)
{
    try 
    {
        AllocateALotOfMemory();
    }
    catch (OutOfMemoryException e)
    {
        // Handle error
    }
}

【讨论】:

  • 子进程的内存分配发生在主应用程序中,而不是在子进程中。在这种情况下,catch 块可以处理OutOfMemoryException 吗?
  • 我从未见过或使用过这个 Job api,但我认为内存不是由主应用程序分配的,即使在这种情况下也是如此。这项工作只是设置了操作系统将强制执行的一些限制。你到底想做什么?为什么你必须限制子进程的内存使用(而不是首先检查它们没有使用太多内存)?我觉得你的方法太复杂了。
最近更新 更多