在 Asp.net 中运行外部可执行文件的内存限制

Posted

技术标签:

【中文标题】在 Asp.net 中运行外部可执行文件的内存限制【英文标题】:Memory limit for running external executables within Asp.net 【发布时间】:2012-08-27 10:11:00 【问题描述】:

我在运行于 .NET 4.0 的 C# Web 应用程序中使用 WkhtmltoPdf 从 HTML 文件生成 PDF。一般来说,除了 HTML 文件的大小低于 250KB 时,一切正常。一旦 HTML 文件大小超过此值,运行 wkhtmltopdf.exe 的进程就会出现如下异常。在任务管理器上,我看到 wkhtmltopdf.exe 进程的内存值没有增加超过 40,096 K 的值,我相信这就是该进程在两者之间被放弃的原因。

我们如何配置以增加外部 exe 的内存限制?有没有其他方法可以解决这个问题?

更多信息: 当我直接从命令行运行转换时,PDF 生成良好。因此,它不太可能是 WkhtmlToPdf 的问题。

错误来自本地主机。我在DEV服务器上也试过了,结果一样。

编辑:

更具体的异常消息: - 对于 MainModule 的属性 进程对象,错误说 - “仅部分 ReadProcessMemory 或 WriteProcessMemory 请求已完成”,带有 NativeErrorCode 值 - 299。

例外:

> [Exception: Loading pages (1/6) [>                                    
> ] 0% [======>                                                     ]
> 10% [======>                                                     ] 11%
> [=======>                                                    ] 13%
> [=========>                                                  ] 15%
> [==========>                                                 ] 18%
> [============>                                               ] 20%
> [=============>                                              ] 22%
> [==============>                                             ] 24%
> [===============>                                            ] 26%
> [=================>                                          ] 29%
> [==================>                                         ] 31%
> [===================>                                        ] 33%
> [=====================>                                      ] 35%
> [======================>                                     ] 37%
> [========================>                                   ] 40%
> [=========================>                                  ] 42%
> [==========================>                                 ] 44%
> [============================>                               ] 47%
> [=============================>                              ] 49%
> [==============================>                             ] 51%
> [============================================================] 100%
> Counting pages (2/6)                                               
> [============================================================] Object
> 1 of 1 Resolving links (4/6)                                          
> [============================================================] Object
> 1 of 1 Loading headers and footers (5/6)                              
> Printing pages (6/6) [>                                               
> ] Preparing [=>                                                       
> ] Page 1 of 49 [==>                                                   
> ] Page 2 of 49 [===>                                                  
> ] Page 3 of 49 [====>                                                 
> ] Page 4 of 49 [======>                                               
> ] Page 5 of 49 [=======>                                              
> ] Page 6 of 49 [========>                                             
> ] Page 7 of 49 [=========>                                            
> ] Page 8 of 49 [==========>                                           
> ] Page 9 of 49 [============>                                         
> ] Page 10 of 49 [=============>                                       
> ] Page 11 of 49 [==============>                                      
> ] Page 12 of 49 [===============>                                     
> ] Page 13 of 49 [================>                                    
> ] Page 14 of 49 [==================>                                  
> ] Page 15 of 49 [===================>                                 
> ] Page 16 of 49 [====================>                                
> ] Page 17 of 49 [=====================>                               
> ] Page 18 of 49 [======================>                              
> ] Page 19 of 49 [========================>                            
> ] Page 20 of 49 [=========================>                           
> ] Page 21 of 49 [==========================>                          
> ] Page 22 of 49 [===========================>                         
> ] Page 23 of 49 [============================>                        
> ] Page 24 of 49 [==============================>                      
> ] Page 25 of 49 [===============================>                     
> ] Page 26 of 49 [=================================>                   
> ] Page 27 of 49 [==================================>                  
> ]

我使用的代码:

    var fileName = " - ";
    var wkhtmlDir = ConfigurationManager.AppSettings[Constants.AppSettings.ExportToPdfExecutablePath];
    var wkhtml = ConfigurationManager.AppSettings[Constants.AppSettings.ExportToPdfExecutablePath] + "\\wkhtmltopdf.exe";
    var p = new Process();


    string switches = "";
    switches += "--print-media-type ";
    switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 5mm --margin-left 5mm ";
    switches += "--page-size A4 ";
    switches += "--disable-smart-shrinking ";

    var startInfo = new ProcessStartInfo
    
        CreateNoWindow = true,
        FileName = wkhtml,
        Arguments = switches + " " + url + " " + fileName,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        RedirectStandardInput=true,
        WorkingDirectory=wkhtmlDir
    ;

    p.StartInfo = startInfo;
    p.Start();

WkHtmlToPdf.exe 进程调试器截图:

【问题讨论】:

也许这有帮助:***.com/a/9270159/135007 您在哪里看到这是内存不足的问题? @SimonMourier:在运行应用程序时,wkhtmltopdf.exe 的内存值在任务管理器中的某个固定限制后不会增加。而通过命令提示符运行相同的命令时,执行就很好了。此外,如果输入的 HTML 文件的大小较小,那么通过应用程序它就可以正常工作。在 HTML 文件的大小固定后,即使是单个附加字符也不起作用。您认为这可能是内存以外的其他问题吗? 这可能是其他问题,是的,因为没有证据表明这是内存问题,异常不清楚,不显示任何有关内存的信息。如果您看到进程内存增加,例如 1 或 2 Gb,则可能是这样,但似乎并非如此。你确定这不是 WkhtmlToPdf 中的错误吗? @SimonMourier:当我通过命令提示符运行 WkhtmlToPdf 时,它工作正常。所以,我认为它与 WkhtmlToPdf 无关。对于 Process 对象的 MainModule 属性,错误显示 - “仅部分 ReadProcessMemory 或 WriteProcessMemory 请求已完成”,NativeErrorCode 值 - 299。 【参考方案1】:

这就是你要找的东西:

http://jobobjectwrapper.codeplex.com/

虽然我听说有人用MaxWorkingSet 限制进程内存,但我找不到与“增加”进程内存限制有关的任何其他内容,但我相信这仅适用于虚拟内存之后应用程序已尽其所能。

作业对象是一个很好的起点,它们只是易于控制的过程的集合。

"使用这个库,您可以创建作业对象,创建和分配一个 工作流程,控制流程和工作限制,并注册 各种流程和作业相关的通知事件。”

这也可能有用:

Calling wkhtmltopdf to generate PDF from HTML

【讨论】:

感谢您的回答。我尝试更改 MaxWorkingSet,但正如您所建议的那样,它似乎不起作用。我在其他一些 SO 帖子中读到,它在执行时总是被修剪到一个更小的值。我必须尝试作业对象包装器,虽然一开始看起来有点复杂。 :-)【参考方案2】:

查看this,看看是否会出现每个进程的线程数限制。这是一个很长的镜头(我不知道 IIS 对外部进程施加的任何内存限制),但请从文档中注意这一点:

因为这个属性定义了 ASP 请求的最大数量 可以同时执行,这个设置应该保持默认 值,除非您的 ASP 应用程序正在扩展调用 外部组件。在这种情况下,您可以增加 每个处理器的线程数限制。这样做允许服务器创建更多 线程来处理更多并发请求。

【讨论】:

感谢您的回答。我不确定它是否与 IIS 有关,因为我尝试从 Windows 应用程序执行类似的代码,并且存在相同的问题。 嗯。两个想法。检查这是否可能是 32/64 位问题。尝试将您的可执行文件显式定位为 32 位或 64 位,看看这是否会有所改变。 (请参阅***.com/questions/10986486/…)其次,我注意到您正在重定向衍生进程的输出,但您没有处理该输出。也许有一个输出缓冲区正在耗尽。尝试为 Process.OutputDataReceived 添加一个事件处理程序来处理输出。或者禁用重定向。

以上是关于在 Asp.net 中运行外部可执行文件的内存限制的主要内容,如果未能解决你的问题,请参考以下文章

identity与ASP.NET 模拟

Asp.net Core 中的内存使用限制

Linux命令执行过程

如何在本地服务结构集群中部署和访问来宾可执行文件(ASP.NET OWIN 自托管 webapi 应用程序)

ASP.Net Worker 进程内存配置文件工具

使用 QProcess 在 Qt 中运行外部可执行文件