异步 PDF 创建的 IOException 问题
IOException issue with asynchronous PDF creation
我有一个异步方法,可以根据从数据库检索到的 XML 创建 PDF 文件。一切正常,但偶尔我会收到 IOException
,因为当我在创建 PDF 后尝试清理临时 .fo
文件时,该文件仍在使用中。
Public Sub FormatObjectToPdf(ByVal intRxNo As Integer, ByVal strSourceFileName As String)
Dim startInfo As New ProcessStartInfo
Dim strPdfFile As String = g_strRootPath & "Paperwork\" & intRxNo & "M.pdf"
' if the PDF file already exists, no need to re-create it
If Not File.Exists(strPdfFile) Then
Try
startInfo.Arguments = "-fo """ & strSourceFileName & """ -pdf """ & strPdfFile & """"
startInfo.FileName = g_strAppPath & "FO.NET\fonet.exe"
startInfo.UseShellExecute = True
startInfo.WindowStyle = ProcessWindowStyle.Hidden
Using proc As Process = Process.Start(startInfo)
proc.WaitForExit()
If proc.HasExited Then
proc.Dispose()
End If
End Using
Catch ex As Exception
Call InsertLog("ErrorLog", "FormatObjectToPdf: " & ex.Message, ex)
MessageBox.Show(ex.Message, "Create PDF", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
End If
' wait 3 seconds to allow file to be released
System.Threading.Thread.Sleep(3000)
' delete the source FO file when processing is complete
If File.Exists(strSourceFileName) Then
Try
File.Delete(strSourceFileName)
Catch iEx As IOException
Call InsertLog("ErrorLog", "Could not delete file '" & strSourceFileName & "': " & iEx.Message, iEx)
Catch ex As Exception
Call InsertLog("ErrorLog", "Error deleting file '" & strSourceFileName & "': " & ex.Message, ex)
End Try
End If
End Sub
FormatObjectToPdf
方法是从另一个方法 AsyncXmlToPdf
调用的,这实际上是抛出 IOException
的地方。我最初认为异常在 FormatObjectToPdf
中,因为那是我删除 .fo
文件的地方,所以我添加了一个 Sleep(3000)
看看给它几秒钟是否有帮助。
这里是 AsyncXmlToPdf
:
Public Sub AsyncXmlToPdf(ByVal state As Object)
Dim intRxNo = state(0)
Dim flgPrintResult As Boolean = state(1)
Dim strFileName As String = g_strAppPath & intRxNo & ".fo"
Dim strOutput As String
Dim strPdfFile As String = g_strRootPath & "Paperwork\" & intRxNo & "M.pdf"
Try
If File.Exists(strPdfFile) Then
File.Delete(strPdfFile)
End If
If Not File.Exists(strPdfFile) AndAlso Not File.Exists(strFileName) Then
strOutput = XmlToFormatObject(intRxNo, g_strAppPath & "FO.NET\immfo.xsl")
Using writer As StreamWriter = New StreamWriter(strFileName)
writer.Write(strOutput)
End Using
Call FormatObjectToPdf(intRxNo, strFileName)
End If
Catch ex As Exception
Call InsertLog("ErrorLog", "AsyncXmlToPdf: " & ex.Message, ex)
End Try
End Sub
除了 strFileName
的声明之外,这两种方法的唯一部分甚至对 .fo
文件做任何事情都在 FormatObjectToPdf
中,并且该方法有一个 Catch
阻止 IOException
。为什么在 AsyncXmlToPdf
中捕获异常?这是实际的错误消息:
3/25/2015 11:15 AM: [IOException] AsyncXmlToPdf: The process cannot access the file 'C:\Users\<username>\AppData\Local\Apps.0M2D4TCB.REJLH3JZY2.TQC\<clickonce app>1964.fo' because it is being used by another process.
除了发生此异常时偶尔出现的孤立 .fo
文件外,一切都按预期工作。有人对我如何找出问题所在有任何建议吗?
The only part of either method ... that even does anything with the .fo file is in FormatObjectToPdf
看来 AsyncXmlToPdf
也会尝试在其上打开一个 streamwriter。
如果其他一些 BackGroundWorker、Thread 或 Task 有可能也在处理同一组文件,那么 AsyncXmlToPdf
和 [= 中可能会使用同一个文件13=]。 MSDN 在 File.Exists
条目中对此发出警告:
Be aware that another process can potentially do something with the file in between the time you call the Exists method and perform another operation on the file, such as Delete.
在您的情况下,看起来可能是抛硬币,异常将在哪个方法中发生。
如果意外双击可以启动同一个进程两次,则可能是同一个文件同时在两种方法中使用。您可以添加另一个测试,看看您是否可以打开文件进行 ReadWrite。鉴于该文件不应该存在,您至少可以确定原因。
阻止启动一组以上作业的某种标志可能是最终解决方案。
我有一个异步方法,可以根据从数据库检索到的 XML 创建 PDF 文件。一切正常,但偶尔我会收到 IOException
,因为当我在创建 PDF 后尝试清理临时 .fo
文件时,该文件仍在使用中。
Public Sub FormatObjectToPdf(ByVal intRxNo As Integer, ByVal strSourceFileName As String)
Dim startInfo As New ProcessStartInfo
Dim strPdfFile As String = g_strRootPath & "Paperwork\" & intRxNo & "M.pdf"
' if the PDF file already exists, no need to re-create it
If Not File.Exists(strPdfFile) Then
Try
startInfo.Arguments = "-fo """ & strSourceFileName & """ -pdf """ & strPdfFile & """"
startInfo.FileName = g_strAppPath & "FO.NET\fonet.exe"
startInfo.UseShellExecute = True
startInfo.WindowStyle = ProcessWindowStyle.Hidden
Using proc As Process = Process.Start(startInfo)
proc.WaitForExit()
If proc.HasExited Then
proc.Dispose()
End If
End Using
Catch ex As Exception
Call InsertLog("ErrorLog", "FormatObjectToPdf: " & ex.Message, ex)
MessageBox.Show(ex.Message, "Create PDF", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
End If
' wait 3 seconds to allow file to be released
System.Threading.Thread.Sleep(3000)
' delete the source FO file when processing is complete
If File.Exists(strSourceFileName) Then
Try
File.Delete(strSourceFileName)
Catch iEx As IOException
Call InsertLog("ErrorLog", "Could not delete file '" & strSourceFileName & "': " & iEx.Message, iEx)
Catch ex As Exception
Call InsertLog("ErrorLog", "Error deleting file '" & strSourceFileName & "': " & ex.Message, ex)
End Try
End If
End Sub
FormatObjectToPdf
方法是从另一个方法 AsyncXmlToPdf
调用的,这实际上是抛出 IOException
的地方。我最初认为异常在 FormatObjectToPdf
中,因为那是我删除 .fo
文件的地方,所以我添加了一个 Sleep(3000)
看看给它几秒钟是否有帮助。
这里是 AsyncXmlToPdf
:
Public Sub AsyncXmlToPdf(ByVal state As Object)
Dim intRxNo = state(0)
Dim flgPrintResult As Boolean = state(1)
Dim strFileName As String = g_strAppPath & intRxNo & ".fo"
Dim strOutput As String
Dim strPdfFile As String = g_strRootPath & "Paperwork\" & intRxNo & "M.pdf"
Try
If File.Exists(strPdfFile) Then
File.Delete(strPdfFile)
End If
If Not File.Exists(strPdfFile) AndAlso Not File.Exists(strFileName) Then
strOutput = XmlToFormatObject(intRxNo, g_strAppPath & "FO.NET\immfo.xsl")
Using writer As StreamWriter = New StreamWriter(strFileName)
writer.Write(strOutput)
End Using
Call FormatObjectToPdf(intRxNo, strFileName)
End If
Catch ex As Exception
Call InsertLog("ErrorLog", "AsyncXmlToPdf: " & ex.Message, ex)
End Try
End Sub
除了 strFileName
的声明之外,这两种方法的唯一部分甚至对 .fo
文件做任何事情都在 FormatObjectToPdf
中,并且该方法有一个 Catch
阻止 IOException
。为什么在 AsyncXmlToPdf
中捕获异常?这是实际的错误消息:
3/25/2015 11:15 AM: [IOException] AsyncXmlToPdf: The process cannot access the file 'C:\Users\<username>\AppData\Local\Apps.0M2D4TCB.REJLH3JZY2.TQC\<clickonce app>1964.fo' because it is being used by another process.
除了发生此异常时偶尔出现的孤立 .fo
文件外,一切都按预期工作。有人对我如何找出问题所在有任何建议吗?
The only part of either method ... that even does anything with the .fo file is in FormatObjectToPdf
看来 AsyncXmlToPdf
也会尝试在其上打开一个 streamwriter。
如果其他一些 BackGroundWorker、Thread 或 Task 有可能也在处理同一组文件,那么 AsyncXmlToPdf
和 [= 中可能会使用同一个文件13=]。 MSDN 在 File.Exists
条目中对此发出警告:
Be aware that another process can potentially do something with the file in between the time you call the Exists method and perform another operation on the file, such as Delete.
在您的情况下,看起来可能是抛硬币,异常将在哪个方法中发生。
如果意外双击可以启动同一个进程两次,则可能是同一个文件同时在两种方法中使用。您可以添加另一个测试,看看您是否可以打开文件进行 ReadWrite。鉴于该文件不应该存在,您至少可以确定原因。
阻止启动一组以上作业的某种标志可能是最终解决方案。