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

C#/.NET Core:多PDF下载合并不落地文件报错排查

问题分析与修复方案

错误根源

你在调用copy.AddDocument(new PdfReader(msX))后立刻Dispose了对应的MemoryStream,但PdfCopyFields执行copy.Close()完成合并时,仍需要读取这些源流的内容。此时流已被释放,就会触发ObjectDisposedException。

修复思路

延迟释放所有源MemoryStream,直到PDF合并操作完全完成(即copy.Close()执行后),再统一清理资源。

修改后的代码

合并PDF部分

MemoryStream finalStream = new MemoryStream();
PdfCopyFields copy = new PdfCopyFields(finalStream);

// 收集所有需要释放的流,最后统一处理
var streamsToCleanup = new List<MemoryStream>();

// 处理第一个URL
var ms1 = new MemoryStream();
streamsToCleanup.Add(ms1);
ConvertToStream(url1, ms1);
ms1.Position = 0;
copy.AddDocument(new PdfReader(ms1));

// 处理第二个URL
var ms2 = new MemoryStream();
streamsToCleanup.Add(ms2);
ConvertToStream(url2, ms2);
ms2.Position = 0;
copy.AddDocument(new PdfReader(ms2));

// 处理批量URL
foreach(string s in psURLs)
{
    var ms3 = new MemoryStream();
    streamsToCleanup.Add(ms3);
    ConvertToStream(s, ms3);
    ms3.Position = 0;
    copy.AddDocument(new PdfReader(ms3));
}

// 先完成PDF合并操作
copy.Close();

// 现在可以安全释放所有源流
foreach(var stream in streamsToCleanup)
{
    stream.Dispose();
}

return finalStream;

下载流方法优化(可选,更规范的资源管理)

private void ConvertToStream(string fileUrl, Stream stream)
{
    using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fileUrl))
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using (Stream response_stream = response.GetResponseStream())
    {
        response_stream.CopyTo(stream, 4096);
    }
}

补充说明

PdfCopyFields并非在调用AddDocument时就把PDF内容写入最终流,而是在Close()阶段才完成所有合并逻辑,这一过程需要所有源PDF流保持可用状态。提前释放源流会导致后续读取操作失败,触发流已关闭的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:40:18