InsertPdf後出現AccessViolationException,附HTML頁首/頁尾
在使用InsertPdf合併來自另一個文件的頁面後,對PdfDocument呼叫AddHtmlHeaders時會拋出AccessViolationException。 在Debug構建中或附加除錯器時,該例外狀況不會發生。
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at IronPdf.PdfDocument.AddHtmlHeaders(...)
在Release構建中,.NET JIT優化器允許垃圾回收器在管理程式碼能證明物件不會被再次引用後,在其詞彙範疇結束之前回收管理物件。 傳遞給InsertPdf的PdfDocument可以在IronPDF的原生Chrome層仍在讀取時被回收。 隨後的AddHtmlHeaders呼叫然後存取已釋放的記憶體,導致存取衝突。
解決方案
選擇1:在InsertPdf之前應用頁首和頁尾(推薦)
重新排列操作順序,使頁首和頁尾在插入任何頁面之前寫入到基本文件中:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:10px'>Page {page} of {total-pages}</div>"
};
var basePdf = renderer.RenderHtmlAsPdf(baseHtml);
basePdf.AddHtmlHeaders(renderer.RenderingOptions.HtmlHeader);
var supplementPdf = PdfDocument.FromFile("supplement.pdf");
basePdf.InsertPdf(supplementPdf, 0);
basePdf.SaveAs("output.pdf");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:10px'>Page {page} of {total-pages}</div>"
};
var basePdf = renderer.RenderHtmlAsPdf(baseHtml);
basePdf.AddHtmlHeaders(renderer.RenderingOptions.HtmlHeader);
var supplementPdf = PdfDocument.FromFile("supplement.pdf");
basePdf.InsertPdf(supplementPdf, 0);
basePdf.SaveAs("output.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:right; font-size:10px'>Page {page} of {total-pages}</div>"
}
Dim basePdf = renderer.RenderHtmlAsPdf(baseHtml)
basePdf.AddHtmlHeaders(renderer.RenderingOptions.HtmlHeader)
Dim supplementPdf = PdfDocument.FromFile("supplement.pdf")
basePdf.InsertPdf(supplementPdf, 0)
basePdf.SaveAs("output.pdf")
選擇2:使用GC.KeepAlive防止過早回收
如果無法改變操作順序,則將來源PdfDocument的受管理生命週期延長至AddHtmlHeaders呼叫之後:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:10px'>Page {page} of {total-pages}</div>"
};
var basePdf = renderer.RenderHtmlAsPdf(baseHtml);
var supplementPdf = PdfDocument.FromFile("supplement.pdf");
basePdf.InsertPdf(supplementPdf, 0);
basePdf.AddHtmlHeaders(renderer.RenderingOptions.HtmlHeader);
GC.KeepAlive(supplementPdf);
basePdf.SaveAs("output.pdf");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:10px'>Page {page} of {total-pages}</div>"
};
var basePdf = renderer.RenderHtmlAsPdf(baseHtml);
var supplementPdf = PdfDocument.FromFile("supplement.pdf");
basePdf.InsertPdf(supplementPdf, 0);
basePdf.AddHtmlHeaders(renderer.RenderingOptions.HtmlHeader);
GC.KeepAlive(supplementPdf);
basePdf.SaveAs("output.pdf");
Imports System
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:right; font-size:10px'>Page {page} of {total-pages}</div>"
}
Dim basePdf = renderer.RenderHtmlAsPdf(baseHtml)
Dim supplementPdf = PdfDocument.FromFile("supplement.pdf")
basePdf.InsertPdf(supplementPdf, 0)
basePdf.AddHtmlHeaders(renderer.RenderingOptions.HtmlHeader)
GC.KeepAlive(supplementPdf)
basePdf.SaveAs("output.pdf")
放置在AddHtmlHeaders之後的GC.KeepAlive(supplementPdf)可防止JIT在原生合併完成前排程回收supplementPdf。

