该进程无法访问该文件,因为它正被另一个进程(iTextSharp c#)使用

该进程无法访问该文件,因为它正被另一个进程(iTextSharp c#)使用,c#,asp.net,itextsharp,C#,Asp.net,Itextsharp,我有一个下载PDF处理程序: // Build the PDF Manual.Functions.createEntireManual(ThisDownload.FileLocation); // Download file context.Response.Clear(); context.Response.Buffer = false; context.Response.ContentType = "application/pdf";

我有一个下载PDF处理程序:

    // Build the PDF
    Manual.Functions.createEntireManual(ThisDownload.FileLocation);

    // Download file
    context.Response.Clear();
    context.Response.Buffer = false;
    context.Response.ContentType = "application/pdf";
    context.Response.AddHeader("Content-disposition", "attachment; filename=Construct2-Manual-Full.pdf");        
    context.Response.AddHeader("Content-Length", FileSize.ToString());
    context.Response.TransmitFile(Settings.ManualBinLocation + ThisDownload.ID + ".pdf");
    context.Response.Close();
创建手动功能如下所示:

public static void createEntireManual(string PDFPath)
{
    iTextSharp.text.Document d = new iTextSharp.text.Document();
    d.Open();

    using (iTextSharp.text.pdf.PdfWriter p = iTextSharp.text.pdf.PdfWriter.GetInstance(d, new FileStream(PDFPath, FileMode.Create)))
    {
        d.Add(new Paragraph("Hello world!"));
    }            
}
这将抛出错误:

Exception Details: System.IO.IOException: The process cannot access the file 'C:\inetpub\wwwroot\manuals\26.pdf' because it is being used by another process.
很好,因此我在函数中添加了
d.Close()

        d.Add(new Paragraph("Hello world!"));            
    }    
    d.Close();        
}
但这会引发:

Exception Details: System.Exception: The document is not open.
d.Close()
行上。我尝试将新文档对象添加为using语句,但它不喜欢这样,抛出了一个无意义的错误:

Exception Details: System.Exception: The document is not open.
在面板上使用闭合支架


有谁对iTextSharp有更丰富的经验来帮我吗?

弄明白了,你不应该对
文档
PDFWriter
对象使用
using
。此代码适用于:

    /// <summary>
    /// Saves the entire manual as PDF
    /// </summary>
    public static void createEntireManual(string PDFPath)
    {
        Document d = new Document();
        PdfWriter.GetInstance(d, new FileStream(PDFPath, FileMode.Create));
        d.Open();
        d.SetPageSize(iTextSharp.text.PageSize.A4);
        Image Cover = Image.GetInstance(Settings.ManualBinLocation + "cover.png");
        Cover.SetAbsolutePosition(0, 0);
        d.Add(Cover);
        d.Close();              

    }
//
///将整个手册另存为PDF
/// 
公共静态void createEntiremanal(字符串PDFPath)
{
文件d=新文件();
GetInstance(d,新文件流(PDFPath,FileMode.Create));
d、 Open();
d、 设置页面大小(iTextSharp.text.PageSize.A4);
Image Cover=Image.GetInstance(Settings.ManualBinLocation+“Cover.png”);
盖。设置绝对位置(0,0);
d、 增加(封面);
d、 Close();
}

您是否需要将PDF保存到文件系统中?否则,直接使用
HttpResponse
对象的
OutputStream
就容易多了。下面是一个简单的例子:

<%@ WebHandler Language="C#" Class="handlerExample" %>
using System;
using System.Web;
using iTextSharp.text;  
using iTextSharp.text.pdf;

public class handlerExample : IHttpHandler {
  public void ProcessRequest (HttpContext context) {
    HttpResponse Response = context.Response;
    Response.ContentType = "application/pdf";
    Response.AddHeader(
      "Content-disposition", 
      "attachment; filename=Construct2-Manual-Full.pdf"
    );  
    using (Document document = new Document()) {
      PdfWriter.GetInstance(
        document, Response.OutputStream
      );
      document.Open();
      document.Add(new Paragraph("Hello World!"));
    }
  }
  public bool IsReusable { get { return false; } }
}

使用制度;
使用System.Web;
使用iTextSharp.text;
使用iTextSharp.text.pdf;
公共类handler示例:IHttpHandler{
公共void ProcessRequest(HttpContext上下文){
HttpResponse Response=context.Response;
Response.ContentType=“application/pdf”;
Response.AddHeader(
“内容处置”,
“附件;文件名=Construct2 Manual Full.pdf”
);  
使用(文档=新文档()){
PdfWriter.GetInstance(
文档,Response.OutputStream
);
document.Open();
添加(新段落(“你好,世界!”);
}
}
公共布尔可重用{get{return false;}}
}

所以说你不应该使用
using
语句是不正确的。上面的例子是简化的,但很容易扩展;根据您对上述方法的命名方式,可能您正在从许多不同的较小的PDF文档中构建PDF手册?

我不确定这是否是答案,但您可能需要关闭您创建的
FileStream
,而不是
iTextSharp.text.Document
。我不在VS前面,所以我无法测试它。静态方法?没有锁?asp.net?文件系统?并发灾难的秘诀。@z0n最好的方法是什么?我需要它来构建PDF,然后提供它。想想如果两个人在几乎相同的时间请求相同但尚未创建的PDF会发生什么。我一直推荐一个很棒的并发和线程教程:@x0n by design两个人不会下载同一本手册。但这并没有反映在相同的代码中。光说这一点是不够的——如果两个人同时下载不同的手册,会发生什么情况呢?