如何忽略外部 Dll 的访问冲突异常 - .NET Core 6
我正在使用 DinkToPDF dll 将 XML 转换为 PDF。
我需要生成 2000 个 PDF。
所以我尝试将 PDF 生成逻辑放入 for 循环中。 它生成前 2 或 3 个 PDF,然后在下一次迭代中因本机异常而崩溃,
这是我的 PDF 生成类。在 for 循环中,Generate() 方法将被调用 2000 次
公共静态类 PDFEngine { 公共静态无效生成(字符串html,字符串目录,字符串文件名) { var转换器 = new BasicConverter(new PdfTools()); 转换器.PhaseChanged += Converter_PhaseChanged; Converter.ProgressChanged += Converter_ProgressChanged; 转换器.Finished += Converter_Finished; 转换器.警告+= Converter_Warning; 转换器.Error += Converter_Error; var doc = new HtmlToPdfDocument() { 全局设置 = { 颜色模式=颜色模式.颜色, 方向=方向.肖像, 纸张尺寸 = PaperKind.A4, }, 对象={ 新的对象设置(){ 页数 = true, Html内容 = html, WebSettings = { DefaultEncoding = "utf-8" }, HeaderSettings = { FontSize = 9, Right = "第 [page] 页,共 [toPage]", Line = true }, FooterSettings = { FontSize = 9, Right = "第 [page] 页,共 [toPage]" } } } }; byte[] pdf =转换器.Convert(doc); if (!Directory.Exists(目录)) { 目录.CreateDirectory(目录); } 使用 (FileStream 流 = new FileStream($"{directory}\\{fileName}", FileMode.Create)) { 流.Write(pdf, 0, pdf.Length); } } 私有静态无效Converter_Error(对象发送者,DinkToPdf.EventDefinitions.ErrorArgs e) { Console.WriteLine("[错误] {0}", e.Message); } 私有静态无效Converter_Warning(对象发送者,DinkToPdf.EventDefinitions.WarningArgs e) { Console.WriteLine("[WARN] {0}", e.Message); } 私有静态无效Converter_Finished(对象发送者,DinkToPdf.EventDefinitions.FinishedArgs e) { Console.WriteLine("转换{0} ", e.Success ? "成功" : "不成功"); } 私有静态无效Converter_ProgressChanged(对象发送者,DinkToPdf.EventDefinitions.ProgressChangedArgs e) { Console.WriteLine("进度已更改 {0}", e.Description); } 私有静态无效Converter_PhaseChanged(对象发送者,DinkToPdf.EventDefinitions.PhaseChangedArgs e) { Console.WriteLine("阶段已更改为 {0} - {1}", e.CurrentPhase, e.Description); } }
System.AccessViolationException: '尝试读取或写入受保护的内容 记忆。这通常表明其他内存已损坏。'
我尝试在每个循环中添加
GC.Collect();
GC.WaitForPendingFinalizers();
,但它不起作用。 我完全意识到这个错误是致命的并且不好继续,但我没有办法处理 2000 个文件。
有没有其他方法可以
- 抑制异常并继续循环
- 通过在不同的应用程序域中运行它来解决此错误?
I'm using DinkToPDF dll to convert an XML to PDF.
I need to generate 2000 PDF's.
So I try to do put the PDF generation logic inside for loop.
It generates first 2 or 3 PDF's and then in the next iteration crashes with a native Exception
This is my PDF generation class. Generate() method will be called 2000 times inside a forloop
public static class PDFEngine { public static void Generate(string html, string directory, string fileName) { var converter = new BasicConverter(new PdfTools()); converter.PhaseChanged += Converter_PhaseChanged; converter.ProgressChanged += Converter_ProgressChanged; converter.Finished += Converter_Finished; converter.Warning += Converter_Warning; converter.Error += Converter_Error; var doc = new HtmlToPdfDocument() { GlobalSettings = { ColorMode = ColorMode.Color, Orientation = Orientation.Portrait, PaperSize = PaperKind.A4, }, Objects = { new ObjectSettings() { PagesCount = true, HtmlContent = html, WebSettings = { DefaultEncoding = "utf-8" }, HeaderSettings = { FontSize = 9, Right = "Page [page] of [toPage]", Line = true }, FooterSettings = { FontSize = 9, Right = "Page [page] of [toPage]" } } } }; byte[] pdf = converter.Convert(doc); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } using (FileStream stream = new FileStream(quot;{directory}\\{fileName}", FileMode.Create)) { stream.Write(pdf, 0, pdf.Length); } } private static void Converter_Error(object sender, DinkToPdf.EventDefinitions.ErrorArgs e) { Console.WriteLine("[ERROR] {0}", e.Message); } private static void Converter_Warning(object sender, DinkToPdf.EventDefinitions.WarningArgs e) { Console.WriteLine("[WARN] {0}", e.Message); } private static void Converter_Finished(object sender, DinkToPdf.EventDefinitions.FinishedArgs e) { Console.WriteLine("Conversion {0} ", e.Success ? "successful" : "unsucessful"); } private static void Converter_ProgressChanged(object sender, DinkToPdf.EventDefinitions.ProgressChangedArgs e) { Console.WriteLine("Progress changed {0}", e.Description); } private static void Converter_PhaseChanged(object sender, DinkToPdf.EventDefinitions.PhaseChangedArgs e) { Console.WriteLine("Phase changed {0} - {1}", e.CurrentPhase, e.Description); } }
System.AccessViolationException: 'Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.'
Since this is an Exception generating from an Unmanaged dll, I can't catch it.
I tried adding
GC.Collect();
GC.WaitForPendingFinalizers();
during every loop but it's not working.
I'm fully aware that this error is fatal and not good to continue but I don't have a way to process 2000 files.
Is there any other way to either
- Suppress the Exception and continue loop
- Resolve this error by running it in a different app domain or something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过大量的试验和错误,我能够以不同的方式使其工作。
我的意图是跑2000次。
我的问题是,当我将它放入循环中时,我遇到了本机异常
为了使其满足我的需要
我删除了循环并仅为单个文件生成 PDF。我在命令行参数中收到的这个文件名
然后我创建了另一个控制台应用程序,它有 2000 次迭代循环,它将调用主应用程序作为
Process.Start();
我可以通过文件名作为参数这样我暂时设法进行任意次数的迭代。由于现在每个进程都有不同的 PID,内存问题不存在
After a lot of trial and error I was able to make it work with a different way.
My intention is to run in 2000 times.
My issue was when I put it inside the loop, I'm getting native exceptions
To make it work for my need
I removed the loop and generate PDF only for a single file. This file name I receive in a commandline argument
Then I created another console app that got a 2000 iteration loop and it'll call the main app as a
Process.Start();
I can pass the filename as argumentsThis way I managed to make for any number of iterations for time being. Since each process got different PID now Memory issue is not there