【发布时间】:2015-04-24 12:35:05
【问题描述】:
我想要实现的是使用 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:line 416 at ConsoleApplication1.Program.c__DisplayClass4.b__3(order currentOrder) 在 ~\Program.cs:line 70 at System.Threading.Tasks.Parallel.c__DisplayClass2d
2.<ForEachWorker>b__23(Int32 i) at System.Threading.Tasks.Parallel.<>c__DisplayClassf1.b__c()
【问题讨论】:
-
谁在使用该 pdf?它是并行循环中的另一个线程吗?
-
不要这样做
throw ex;,如果这样做,您将丢失堆栈跟踪。要么做throw;,要么根本没有catch,你可以有一个try,有一个finally,没有catch。 -
@SriramSakthivel,是的,我认为这可能是另一个可能导致问题的线程
-
如果是这样,你为什么还要在两个线程中访问它?为什么会有碰撞?
invoiceNumber在列表中不是唯一的吗? -
@YuvalItzchakov
PdfWriter在他的代码中暗示他写了:)
标签: c# multithreading pdf itextsharp