并行处理以创建PDF

时间:2015-04-24 12:35:06

标签: c# multithreading pdf itextsharp

我想要实现的是使用iTextSharp程序集进行多线程生成发票。

在我使用Parallel.ForEach的理解中,它将采用IEnumerable源并将其委托给不同的线程。

现在我遇到的问题是1个进程正在尝试访问另一个进程正在使用的文件。

  

该过程无法访问该文件' ... \ Invoices \ INV0000089576PPN.pdf'因为它正被使用   另一个过程。

如何防止这种情况发生?

线程处理

Task task = new Task(() =>
   {
      Parallel.ForEach(orders, currentOrder =>
      {
                LiveTrainingEntities db = new LiveTrainingEntities();
                var trans = db.Transactions.SingleOrDefault(x => x.fTransactionID == currentOrder.TransactionID);

                if (trans != null)
                {
                    var labOrderInvoices = GetLabOrderInvoices(trans.Practices.fPracticeID, currentOrder.TaxInvoiceNumber);
                    CreateLabOrderInvoice(PopulateHTML(labOrderInvoices), currentOrder.TaxInvoiceNumber);

                    Console.WriteLine("Processing {0} on thread {1}", currentOrder.TaxInvoiceNumber,
                                Thread.CurrentThread.ManagedThreadId);

                    //orders.Remove(currentOrder);
       }
   });
});
task.Start();
task.Wait();

PDF方法

static void CreateLabOrderInvoice(string html, string invoiceNumber)
    {
        try
        {
            string strHtml = null;
            MemoryStream memStream = new MemoryStream();

            strHtml = html;

            string strFileShortName = invoiceNumber + ".pdf";
            string strFileName = @"~\Invoices\" + strFileShortName;
            iTextSharp.text.Document docWorkingDocument = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 40, 40, 40, 40);
            StringReader srdDocToString = null;

            try
            {
                PdfWriter pdfWrite = default(PdfWriter);

                pdfWrite = PdfWriter.GetInstance(docWorkingDocument, new FileStream(strFileName, FileMode.Create));
                srdDocToString = new StringReader(strHtml);

                docWorkingDocument.Open();

                Image logo = Image.GetInstance(@"~\images\Image_PPNLOGO.jpg");
                logo.Alignment = Image.ALIGN_RIGHT;

                docWorkingDocument.AddTitle("Lab Order Invoice");
                docWorkingDocument.Add(logo);

                XMLWorkerHelper.GetInstance().ParseXHtml(pdfWrite, docWorkingDocument, srdDocToString);
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            finally
            {
                if ((docWorkingDocument != null))
                {
                    docWorkingDocument.Close();
                }
                if ((srdDocToString != null))
                {
                    srdDocToString.Close();
                    srdDocToString.Dispose();
                }
            }
        }
        catch (System.Exception ex)
        {
            throw ex;
        }


    }

修改 这是堆栈跟踪

  

在ConsoleApplication1.Program.CreateLabOrderInvoice(String html,   字符串invoiceNumber)在〜\ Program.cs:第416行   ConsoleApplication1.Program&LT;&GT; c__DisplayClass4.b__3(顺序   currentOrder)在〜\ Program.cs:第70行   System.Threading.Tasks.Parallel&LT;&GT; c__DisplayClass2d 2.<ForEachWorker>b__23(Int32 i) at System.Threading.Tasks.Parallel.<>c__DisplayClassf 1.b__c()

1 个答案:

答案 0 :(得分:1)

您的问题是,通过使用currentOrder.TaxInvoiceNumber字段的值作为唯一唯一的鉴别符,您可以为特定订单生成PDF的文件名。

但是,从你得到的错误中可以清楚地看出,它并不像你想象的那么独特,似乎某些订单对这个字段具有相同的价值。

您的选择:

  1. 不仅可以通过订单对订单/税务发票编号组合进行分区。
  2. 使用两个ID的组合(即订单ID +税务发票编号)生成文件名
  3. 使用序列Id +税务发票编号作为文件名,以确保其唯一。