ASP.NET ¿Cómo espero la carga / liberación de archivos?
-
26-09-2020 - |
Pregunta
Tengo la aplicación ASP.NET Intranet escrita en VB.Obtiene un archivo del usuario, y luego dependiendo de algunos casos diferentes, puede crear algunas copias del archivo, así como mover el original.
Desafortunadamente, he encontrado un caso en el que obtengo este error:
Exception Details: System.IO.IOException: The process cannot access the file
'\\some\dir\D09_03_5_180_0.000-6.788.png' because it is being used by
another process.
que es lanzado por My.Computer.FileSystem.CopyFile
.Y eso está bien que está siendo utilizado por otro proceso, ¡aún puede estar ahorrando / descargando del usuario o tratando de copiar mientras otro hilo (?) Está copiando, realmente no me importa eso, lo que quiero saber:
¿Hay alguna forma de que pueda decir que VB espere a copiar (también mover) el archivo hasta que el archivo ya no esté en uso?
gracias
Solución
Pruebe si el archivo está en uso y haga lo que necesita hacer.
PUBLIC Sub WritanLogFile (BYVAL PText como cadena, Byval PSpath como cadena, PSNAME BYVAL como cadena)
Dim strFullFileName As String
Dim Writer As System.IO.StreamWriter
Dim Fs As System.IO.FileStream
Try
Dim DirectoryHandler As New System.IO.DirectoryInfo(psPath)
strFullFileName = psPath & "\" & psName & Date.Today.Month.ToString & "-" & Date.Today.Day.ToString & "-" & Date.Today.Year.ToString & ".txt"
If Not DirectoryHandler.Exists() Then
Try
Monitor.Enter(fsLocker)
DirectoryHandler.Create()
Finally
Monitor.Exit(fsLocker)
End Try
End If
Try
If CheckIfFileIsInUse(strFullFileName) = True Then
Thread.Sleep(500) ' wait for .5 second
WriteLogFile(pText, psPath, psName)
If Not Fs Is Nothing Then Fs.Close()
If Not Writer Is Nothing Then Writer.Close()
Exit Sub
End If
Monitor.Enter(fsLocker)
Fs = New System.IO.FileStream(strFullFileName, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Write)
Writer = New System.IO.StreamWriter(Fs)
Writer.WriteLine(Date.Now.ToString & vbTab & "ProcessID: " & Process.GetCurrentProcess.Id.ToString() & vbTab & pText)
Writer.Close()
Fs.Close()
Finally
Monitor.Exit(fsLocker)
End Try
Catch ex As Exception
Dim evtEMailLog As System.Diagnostics.EventLog = New System.Diagnostics.EventLog()
evtEMailLog.Source = Process.GetCurrentProcess.ProcessName.ToString()
evtEMailLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error)
Finally
If Not Fs Is Nothing Then Fs.Close()
If Not Writer Is Nothing Then Writer.Close()
End Try
final sub Función pública CheckiffileInusa (Byval Sfile como cadena) como booleano If system.io.file.exists (sfile) entonces Intentar DIM F como corto= FreeFile () FileOpen (F, SFile, OpenMode.Aply, OpenAccess.Write, OpenShare.Shared) FILECLOSE (F) Captura Devolver verdadero Intento final Terminara si Función final
Otros consejos
hmm ... no directamente. Lo que está haciendo la mayoría de las implementaciones, está haciendo un reintento de copiar el archivo, con un pequeño plazo (algunos segundos)
Si desea hacer una UI agradable, verifique a través de AJAX, si el proceso de copia fue bien.
Bueno, resulta que la espera no funcionaría en este caso:
Al intentar copiar un archivo, no puede copiar un archivo de una ubicación a la misma ubicación o tirará un error (aparentemente).En lugar de simplemente fingir copiar el archivo, VB realmente intenta copiar el archivo y falla porque la operación de copia está intentando copiar al archivo que está copiando de (con overwrite:=True
al menos).
whoops!