我有一个由其他人创建的方法,但无权访问该来源。此方法在文件系统上创建PDF文档,但是当我开始传递200多个图像时,我遇到了内存问题。 据我所知,它将对象加载到内存中以呈现PDF,然后输出到文件系统。当我使用for或foreach循环来整理我的文件并输出它时,我可以在任务管理器中看到内存正在缓慢构建,它确实会不时地下降,但总的来说它总是在上升。
这是我的代码:
for(int i = 0; i < Documents.Count; i++)
{
IDocument document = Documents[i];
try
{
string exportFileName = string.Format("{0}_{1}_{2}_{3}", batchName, document.Field("NHS File\\SectionName").Text, document.Field("NHS File\\Classification Result").Text, dateTime);
string imageFileName = exportFileName;
int tries = 0;
while (File.Exists(Path.Combine(processingLocation, imageFileName + ".pdf")))
{
imageFileName = string.Format("{0}_{1}", exportFileName, tries++);
}
document.SaveAs((Path.Combine(processingLocation, imageFileName)), ExportOptions.GetImageOptions());
}
catch(Exception ex)
{
Processing.ReportError(ex.ToString());
return;
}
finally
{
Marshal.ReleaseComObject(document);
Marshal.FinalReleaseComObject(document);
document = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
问题在于'document.SaveAs();' 我已经尝试调用垃圾收集器并释放COM对象,添加和消除内存压力,但似乎没有任何工作我不断得到“System.Runtime.InteropServices.COMException(0x80004005):没有足够的内存!”当它达到200个文件时。
似乎没有close(),Dispose()或Finalize()选项。
有没有办法调用这个document.SaveAs(),以便对象使用的内存由我控制和释放?
提前致谢。
答案 0 :(得分:1)
如果您无法控制第三方代码,则几乎没有选项来清理内存。代码的性质似乎暗示它在COM Interop或平台调用中很重要,如果做错了,这是一种可靠的泄漏内存方式。 GC.Collect
不收集本机分配的内存,因为它不在垃圾收集器的知识之内。
我建议将您的逻辑放在一个单独的进程中,当处理完成后,让进程退出。退出进程是清理资源和内存的一种非常可靠的方法。
将代码移动到控制台应用程序中,并使用Process.Start从当前代码启动新的命令行实用程序。如果您想要同步,请使用WaitForExit
,并且您可以将参数传递给流程,例如要处理的文件或目录的路径。