2011-11-07 51 views
1

我有一個生成PDF文件的vb.net MVC3 Razor應用程序。問題是,如果2個獨立的用戶點擊,同時打印按鈕,它拋出以下異常..:延遲文件讀取/寫入,直到完成使用?

The process cannot access the file 'E:\web\xxxxxxxxxxsonl\PDF_Files\MailingLables.pdf' because it is being used by another process. 

    All of the controller actions to do with printing are basically like below: 

Function Ind_Cert(ByVal firstName As String, ByVal lastname As String, ByVal classRef As String) 
     Dim _Attendance As attendance = db.attendances.Where(Function(f) f.Completed_Class = "Completed" And f.firstName = firstName And f.lastName = lastname).FirstOrDefault 
     If Not IsNothing(_Attendance) Then 
      Dim _reg_classes As List(Of reg_classes) = db.reg_classes.ToList 
      Dim _registrants As List(Of reg_info) = db.reg_info.ToList 
      Dim _courses As List(Of cours) = db.courses.ToList 
      Dim _Board As List(Of board_members) = db.board_members.ToList 
      Dim Board_Member As board_members = _Board.Where(Function(f) f.Official_Cap = "xxxxxx President").FirstOrDefault 
      Dim RecordId As Integer = 0 
      Dim conf_info As conf_info = db.conf_info.Single(Function(r) r.id = 0) 
      Dim conf_num As Integer = conf_info.conf_number 
      Dim _conf_num As String = conf_num.ToString 
      Dim Length As Integer 
      Dim _prefix As String = String.Empty 

      If Str(conf_num) <> "" Then 
       Length = Str(conf_num).Length 
      End If 


      Dim Divisor As Integer = 10^(Length - 1) 
      Dim conf_num_start As Integer = 0 
      Dim Digits(Length - 1) As Integer 

      While (conf_num > 10) 

       'Extract the first digit 
       Digits(conf_num_start) = Int(conf_num/Divisor) 

       'Extract remainder number - and store it back in Num 
       conf_num = conf_num Mod Divisor 

       'Decrease Divisor's value by 1/10th units 
       Divisor /= 10 

       'Increment Index 
       conf_num_start += 1 

      End While 


      If conf_num = 0 Or 4 Or 5 Or 6 Or 7 Or 8 Or 9 Then _prefix = "th" 
      If conf_num = 1 Then _prefix = "st" 
      If conf_num = 2 Then _prefix = "nd" 
      If conf_num = 3 Then _prefix = "rd" 




      Dim pdfpath As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory) + "\PDF_Files\" 
      Dim imagepath As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory) + "\PDF_Files\" 
      Dim _PdfName As String = "Cert_" + lastname + ".pdf" 
      Dim doc As New Document 
      doc.SetPageSize(iTextSharp.text.PageSize.LETTER.Rotate()) 
      doc.SetMargins(1, 1, 1, 1) 
      Dim _pageCounter As Integer = 0 

      Dim Californian As BaseFont = BaseFont.CreateFont(Path.Combine(AppDomain.CurrentDomain.BaseDirectory) + "\Fonts\" + "CALIFB.TTF", BaseFont.CP1252, BaseFont.EMBEDDED) 
      Dim Copper As BaseFont = BaseFont.CreateFont(Path.Combine(AppDomain.CurrentDomain.BaseDirectory) + "\Fonts\" + "COPRGTB.TTF", BaseFont.CP1252, BaseFont.EMBEDDED) 
      Dim Bold_Times As BaseFont = BaseFont.CreateFont(BaseFont.TIMES_BOLD, BaseFont.CP1252, False) 
      Dim BF_Times As BaseFont = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, False) 
      Dim F_Name As New Font(BF_Times, 16, Font.BOLD, BaseColor.BLACK) 
      Dim _Parking_Name As New Font(BF_Times, 18, Font.NORMAL, BaseColor.BLACK) 
      Dim _Parking_Date As New Font(BF_Times, 24, Font.BOLD, BaseColor.BLACK) 

      '**********************************Y lines for trial*********************************** 
      Dim y_line1 As Integer = 670 
      Dim _Counter As Integer = 1 
      Dim _Page As String = 1 





      Dim _CertJpg As Image = Image.GetInstance(imagepath + "/cert.jpg") 
      Dim imageWidth As Decimal = _CertJpg.Width 
      Dim imageHeight As Decimal = _CertJpg.Height 
      Dim writer As PdfWriter = PdfWriter.GetInstance(doc, New FileStream(pdfpath + _PdfName, FileMode.Create)) 
      doc.Open() 
      Dim cb As PdfContentByte = writer.DirectContent 


      If _Attendance.Completed_Class = "Completed" Then 

       Dim _confInfo As conf_info = db.conf_info.Single(Function(a) a.id = 0) 
       Dim year As String = Right(_confInfo.conf_start_date, 4) 
       Dim _reg As reg_info = db.reg_info.Single(Function(b) b.id = _Attendance.reg_id) 
       Dim name As String = _reg.first_name + " " + _reg.last_name 
       Dim _dates As String = _confInfo.conf_start_date + " - " + _confInfo.conf_end_date 
       Dim _course As cours = db.courses.Single(Function(c) c.course_ref = _Attendance.course_ref) 
       Dim _className As String = _course.course_title.ToString 
       Dim _hours As String = _course.course_hours 
       Dim _certName As String = Board_Member.First_Name + " " + Board_Member.last_name 


       _CertJpg.Alignment = iTextSharp.text.Image.UNDERLYING 
       _CertJpg.ScaleToFit(792, 611) 
       doc.Add(_CertJpg) 

       cb.BeginText() 
       cb.SetFontAndSize(Californian, 36) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "CERTIFICATE OF COMPLETION", 396, 397.91, 0) 
       cb.SetFontAndSize(Bold_Times, 22) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, name, 396, 322.35, 0) 
       cb.SetFontAndSize(Bold_Times, 16) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _hours + " Hours", 297.05, 285.44, 0) 
       cb.SetFontAndSize(Bold_Times, 16) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _dates, 494.95, 285.44, 0) 
       cb.SetFontAndSize(Bold_Times, 16) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Class Attended: " + " " + _Attendance.course_ref + " -- " + _className, 396, 230.34, 0) 
       cb.SetFontAndSize(Copper, 16) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _conf_num + _prefix + " Annual Conference " + _dates, 396, 193.89, 0) 
       cb.SetFontAndSize(Bold_Times, 13) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _certName, 396, 175.69, 0) 
       cb.SetFontAndSize(Bold_Times, 10) 
       cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "xxxxxxx President", 396, 162.64, 0) 
       cb.EndText() 

      End If 

      doc.Close() 
      Return _PdfName 
     Else 
      Return "Fail" 
     End If 


    End Function 

發生此錯誤就像我說的任何時候用戶嘗試生成在同一個PDF文件時間。任何人都知道這個問題的解決辦法? Google已經發布了無數頁面,因爲有人無法刪除Windows中的文件,因爲它正在被使用。但是,這並沒有太大的幫助..任何想法?

回答

2

你幾乎可以做兩件事。

  1. 添加的文件的鎖定並阻止所述第二(以及第三和第四,等等),直到鎖被清零

  2. 爲每個實例創建一個唯一的文件。

我推薦#2。您可以保留相同的文件名,只需將該文件放在一個唯一的目錄中即可。一個GUID通常最容易的是我:

Dim pdfpath As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory) + "\PDF_Files\" 
pdfPath = Path.Combine(pdfPath, Guid.NewGuid.ToString()) 
Directory.CreateDirectory(pdfPath) 

然後改變你的回報,包括上面創建的路徑。

+0

沒想到它是文件名的..原因是,當我被迫錯誤,同時我用2個不同的用戶發生和選擇2個不同的PDF生成功能..其中的功能是相似的,但對於這兩個功能,pdf名稱實際上是不同的。 – Skindeep2366

+0

工作得很好,正是我所需要的。我還爲doc添加了一個配置。沒有更多的問題,它也使得下載後不需要的pdf文件更容易清理,因爲它每次都會生成一個新文件,以確保包含的數據是最新的。再次感謝幫助 – Skindeep2366

2

您是否可以使用隨機文件名創建PDF文件以避免衝突呢?

0

將文件訪問代碼封裝在一個鎖中。

lock (this) 
    { 
    //Write file 
    } 

Lock on MSDN

相關問題