You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac M1环境下DinkToPDF类库测试中转换进程挂起求助

问题描述

我正尝试在应用中集成DinkToPDF将HTML报表转换为PDF。基于开发者示例制作的控制台PoC运行正常——wkhtmltopdf进程启动、上报进度并以代码0完成。

但将相同代码应用于包含多个服务的类库,并通过xunit测试(借助fixture获取服务)测试该特定服务时,转换进程启动后上报10%进度就停止响应,需手动终止,且无日志、无异常抛出。

控制台应用与类库使用相同.NET框架,仅测试方式不同,请问可能的问题原因是什么?

可能的原因及解决方案
  • 线程同步上下文差异:XUnit测试的同步上下文和控制台程序不同,DinkToPDF内部的异步操作可能受限于测试环境的同步上下文,导致进程卡住。可以尝试用Task.Run包裹转换逻辑,或者在测试项目中通过ConfigureAwait(false)禁用同步上下文绑定。
  • 权限与临时目录问题:测试运行进程的权限可能低于控制台,无法访问DinkToPDF默认使用的临时文件目录(转换时会生成临时HTML文件)。可以手动指定有权限的临时目录:
    var pdfTools = new PdfTools { TempFolder = @"C:\Temp\PdfTemp" };
    var converter = new BasicConverter(pdfTools);
    
    确保该目录存在且测试账户有读写权限。
  • 测试进程隔离限制:XUnit默认会并行运行测试或使用隔离进程,可能限制了子进程(wkhtmltopdf)的创建与通信。可以修改测试配置:在xunit.runner.json中设置parallelizeTestCollections为false,或者降低并行度,避免进程冲突。
  • 事件处理阻塞:注册的PhaseChanged、ProgressChanged等事件处理方法中可能存在阻塞逻辑(比如等待未初始化的UI资源),测试环境中无对应资源导致卡住。可以暂时移除事件监听,测试核心转换逻辑是否正常。
  • 依赖库缺失:虽然控制台环境正常,但测试运行环境可能缺少wkhtmltopdf依赖的VC运行时库。确认测试机器安装了对应版本的VC Redistributable,或者将依赖的DLL文件复制到测试项目的输出目录。
相关代码

转换代码

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 = content,
            HtmlContent = @"<html><body><h1>Test</h1></body></html>",
            WebSettings = { DefaultEncoding = "utf-8" },
            FooterSettings = { FontSize = 9, Right = "Page [page] of [toPage]" },
            LoadSettings = { BlockLocalFileAccess = false }
        }
    }
};
byte[] pdf = converter.Convert(doc);

测试代码

var srv = fixture.Provider.GetService<IReportGenerator>();

var req = new ReportReq 
{ 
    TemplateName = "test_report",
    Lang = "en-US",
    Data = new Dictionary<string, object>
    {
        { "Text", "Some test text..." }
    },
};
var res = srv.Generate(req, test_template_dir);

内容的提问来源于stack exchange,提问作者Kal800

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 03:05:04