Come ritardare un programma vb.net fino al completamento di un'operazione sui file?
Domanda
Ho questo:
Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"
System.IO.File.Copy(myFile, "c:\" & myTemp)
Application.DoEvents()
OpenFile(myTemp)
Il problema è che quando chiamo OpenFile, che è solo una chiamata a un sub che apre un file, non riesce a trovare il file. Questo perché lo chiama così rapidamente che il programma non ha il tempo di creare effettivamente il file prima che avvenga l'apertura.
Ho pensato che DoEvents () avrebbe rettificato questo, ma non è così. Devo attendere fino alla creazione del file prima di aprire il file. Come posso farlo?
Soluzione
Non conosco molto VB.NET, ma Copia non è una chiamata bloccante? Sei sicuro di non voler solo aprire il file da una posizione errata (o la barra rovesciata senza caratteri invalida il percorso)?
Che dire di questo? Ho aggiunto la lettera di unità a OpenFile e ho evitato la barra rovesciata in entrambi i punti.
Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"
System.IO.File.Copy(myFile, "c:\\" & myTemp)
OpenFile("c:\\" & myTemp)
Altri suggerimenti
Idealmente dovresti eseguire la copia su un thread separato che informa il thread della GUI principale quando viene fatto in modo che possa quindi eseguire l'apertura tramite una chiamata Invoke.
Usa FileSystemWatcher per avvisarti quando il file viene creato. Nessun loop.
https: //web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6165137.html
Questo è brutto ma funziona per me
Function WaitForFile(fullPath, wdelay)
Dim vd_start As Date
vd_start = Now()
Dim vd_end As Date
Dim wsec, wmin, whour, wt5string As Integer
Dim wtstring As String
Dim count As Integer
Dim wscale As Integer
Dim vd_1 As Date
Dim Vo_fileinfo As FileInfo
Dim fs As FileStream
wsec = Format(wdelay Mod 60, "00")
wmin = Format(Int(wdelay / 60), "00")
whour = Format(Int(wdelay / (60 * 60)), "00")
wtstring = CStr(whour) + ":" + CStr(wmin) + ":" + CStr(wsec)
Dim duration = New System.TimeSpan(0, whour, wmin, wsec)
vd_end = vd_start.Add(duration)
On Error GoTo error1
Dim vsize1, vsize2 As Long
While vd_start < vd_end
fs = New FileStream(fullPath, FileMode.Open)
fs.ReadByte()
fs.Seek(0, SeekOrigin.Begin)
fs.Close()
Vo_fileinfo = New FileInfo(fullPath)
vsize1 = Vo_fileinfo.Length
Threading.Thread.Sleep(500)
Vo_fileinfo = New FileInfo(fullPath)
vsize2 = Vo_fileinfo.Length
If vsize1 <> vsize2 Then GoTo error1
GoTo finalgoto
error1:
Err.Clear()
vd_start = Now()
End While
WaitForFile = False
GoTo Endgoto
finalgoto: WaitForFile = True
Endgoto:
End Function
Questo è un po 'confuso, ma dovrebbe funzionare.
Do Until (System.IO.File.Exists("C:\" & myTemp))
Threading.Thread.Sleep(1)
Loop
Questo non è davvero ciò per cui Doevents è utilizzato. Viene utilizzato più frequentemente per far svuotare la coda dei messaggi dell'interfaccia utente (consentire all'UI di avere un po 'di tempo di aggiornamento della CPU). È leggermente più complesso di quello che sto descrivendo, ma non è questo il punto della tua domanda, quindi andrò avanti.
Prova questo per rendere la sezione critica del tuo blocco di codice:
SyncLock Me
System.IO.File.Copy(myFile, "c:\" & myTemp)
Application.DoEvents()
End SyncLock
OpenFile(myTemp)
Oltre alla risposta di Tom, non è meglio mettere un Application.DoEvents () piuttosto che far dormire il thread?
Innanzitutto, non dovresti chiamare DoEvents da nessuna parte. Per la maggior parte, quando viene utilizzato, è un hack aggirare quella che dovrebbe essere davvero un'operazione asincrona.
Detto questo, il metodo Copia
è un'operazione sincrona . La chiamata a OpenFile
non verrà eseguita fino al completamento della chiamata a Copia
.
Detto questo quando si verifica la chiamata a OpenFile
, se il file non esiste, è perché l'hai copiato nel posto sbagliato o perché qualche altro processo sta funzionando sul file in questione .
I thinf Synclock non va bene in questo caso
per spiegazione, MSDN può aiutarmi
L'istruzione SyncLock garantisce che più thread non eseguano le stesse istruzioni contemporaneamente. Quando il thread raggiunge il blocco SyncLock, valuta l'espressione e mantiene questa esclusività fino a quando non ha un blocco sull'oggetto che viene restituito dall'espressione. Ciò impedisce a un'espressione di modificare i valori durante l'esecuzione di più thread, il che può fornire risultati imprevisti dal codice.
a mio avviso, la copia è un metodo di blocco, quindi il thread attende fino al termine della copia
non può essere un problema in un altro posto?
dim SourceFile as string
dim DestinationFile as string
SourceFile = "c:/archivo.txt"
DestinationFile = "c:/destino/archivo.txt"
If System.IO.File.Exists(SourceFile) = True Then
System.IO.File.Copy(SourceFile, DestinationFile, True)
'or
'My.Computer.FileSystem.CopyFile(SourceFile, DestinationFile, FileIO.UIOption.AllDialogs, FileIO.UICancelOption.DoNothing)
SourceFile = ""
DestinationFile = ""
else
MessageBox.Show("the file don't copy!")
end if
System.Threading.Thread.Sleep (1000);