У меня есть асинхронный метод, который создает файл PDF из XML, извлеченного из базы данных. Все работает отлично, но иногда я получаю IOException
, потому что когда я пытаюсь очистить временный файл .fo
после создания PDF-файла, файл все еще используется.Проблема с IOException с асинхронным созданием PDF
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\2.0\1M2D4TCB.REJ\3LH3JZY2.TQC\<clickonce app>\561964.fo' because it is being used by another process.
Все работает, как ожидалось, кроме случайного сиротского .fo
файла, когда происходит это исключение. У кого-нибудь есть предложения о том, как я могу узнать, где проблема?
'Единственная часть любого из методов ... что даже делает что-либо с файлом .fo в формате FormatObjectToPdf', похоже, что' AsyncXmlToPdf' пытается открыть StreamWriter на нем. Если он заблокирован/используется, что может вызвать исключение, я бы ожидал, что локальный catch сообщит об этом. Возможно, после того, как тест File.Exists попытается открыть его для записи в новом блоке Try и зарегистрировать сбой в новом Catch. Я не уверен, как отправить правильный SO * ответ * на вопрос, требующий «предложений» ... если он не работает, я думаю? – Plutonix
В 'AsyncXmlToPdf', у меня есть' StreamWriter', завернутый в блок 'Using', поэтому я думал, что будет гарантировать, что все будет правильно выпущено после выхода из блока' Using'. Кроме того, я только открываю 'StreamWriter', если файл еще не существует, чтобы не перезаписывать его. –
Да, это не кажется вероятным, но прочитайте раздел REMARKS в MSDN о File.Exists. Может ли что-то еще использовать/создавать одно и то же имя файла в другом месте? – Plutonix