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
相关产品推荐
相关产品推荐

