如何处理.NET MAUI中SkiaSharp.SKDocument的BeginPage()无报错调试终止问题
.NET MAUI + SkiaSharp PDF生成调试终止问题
我正在用SkiaSharp开发.NET MAUI移动端应用,需求是生成指定日期的库存盘点表PDF并分享。代码能正常编译,但调试时执行到document.BeginPage()这一行,程序直接终止且无报错。相关代码片段如下:
public async Task<SKDocument> GenerateInventoryItemCountPdfAsync(DateTime date, List<Item> items, string pdfLogoPath, string pdfTitle) { var stream = new MemoryStream(); using var document = SKDocument.CreatePdf(stream); var pageSize = new SKSize(595, 842); using var canvas = document.BeginPage((int)pageSize.Width, (int)pageSize.Height); using (var logoBitmap = SKBitmap.Decode(pdfLogoPath)) { var logoRect = SKRect.Create(pageSize.Width / 2 - logoBitmap.Width / 2, 50, logoBitmap.Width, logoBitmap.Height); canvas.DrawBitmap(logoBitmap, logoRect); var titlePaint = new SKPaint { Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright), TextSize = 24, IsAntialias = true, Color = SKColors.Black // 后续代码省略 }; } }
排查与解决建议
检查Logo文件路径有效性:如果
pdfLogoPath指向的文件不存在、路径错误或格式不支持,SKBitmap.Decode会抛出未捕获的异常直接终止进程。先加文件存在性判断:if (!File.Exists(pdfLogoPath)) { throw new FileNotFoundException("Logo文件不存在", pdfLogoPath); }修正对象生命周期问题:当前方法返回
SKDocument,但它被using包裹,方法结束时document会被自动释放,调用方使用时会触发异常。建议改为返回MemoryStream,确保PDF内容完整保留:public async Task<MemoryStream> GenerateInventoryItemCountPdfAsync(DateTime date, List<Item> items, string pdfLogoPath, string pdfTitle) { var stream = new MemoryStream(); using var document = SKDocument.CreatePdf(stream); var pageSize = new SKSize(595, 842); using var canvas = document.BeginPage((int)pageSize.Width, (int)pageSize.Height); // 执行所有绘制逻辑... document.EndPage(); document.Close(); stream.Position = 0; // 重置流指针到起始位置 return stream; }匹配SkiaSharp依赖版本:确保项目中
SkiaSharp和SkiaSharp.NativeAssets.Maui的版本完全一致,版本不兼容会导致底层渲染异常。捕获全局未处理异常:在
App.xaml.cs中添加全局异常处理,排查隐藏的异常信息:protected override void OnStart() { AppDomain.CurrentDomain.UnhandledException += (sender, args) => { var exception = args.ExceptionObject as Exception; System.Diagnostics.Debug.WriteLine($"未处理异常: {exception?.Message}\n{exception?.StackTrace}"); }; }避免字体加载失败:移动端可能没有Arial字体,换成系统默认字体或嵌入自定义字体,比如:
Typeface = SKTypeface.Default, // 或者嵌入字体文件后加载 // Typeface = SKTypeface.FromFile("Assets/Fonts/CustomFont.ttf")
内容的提问来源于stack exchange,提问作者Conrad Budde
相关产品推荐
相关产品推荐

