问题
I have this:
Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"
System.IO.File.Copy(myFile, "c:\" & myTemp)
Application.DoEvents()
OpenFile(myTemp)
The problem is that when I call OpenFile, which is just a call to a sub that opens a file, it cannot find the file. This is because it is calling it so quickly that the program doesn't have time to actually create the file before the open takes place.
I thought that DoEvents() would rectify this but it does not. I need to wait until the file is created before I open the file. How can I do that?
回答1:
I don't really know much VB.NET, but isn't Copy a blocking call? Are you sure you're not just trying to open the file from the wrong location (or the unescaped backslash invalidates the path)?
What about this? I've added the drive letter to OpenFile, and escaped the backslash both places.
Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"
System.IO.File.Copy(myFile, "c:\\" & myTemp)
OpenFile("c:\\" & myTemp)
回答2:
Ideally you should perform the copy on a separate thread that informs the main GUI thread when it is done so it can then perform the open through an Invoke call.
回答3:
Use FileSystemWatcher to alert you when the file is created. No loops.
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6165137.html
回答4:
This is ugly but it works for 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
回答5:
This is a bit hacky, but it should work.
Do Until (System.IO.File.Exists("C:\" & myTemp))
Threading.Thread.Sleep(1)
Loop
回答6:
That isn't really what Doevents is used for. It is most frequently used to let the UI message queue clear out (let the UI have some CPU time to refresh). It is slightly more complex than I am describing, but that isn't the point of your question so I will move on.
Try this to make the critical section of your code block:
SyncLock Me
System.IO.File.Copy(myFile, "c:\" & myTemp)
Application.DoEvents()
End SyncLock
OpenFile(myTemp)
回答7:
In addition to Tom's answer, isnt it better to put a Application.DoEvents() rather then making the thread sleep?
回答8:
First, you should not call DoEvents anywhere. For the most part, when it is used, it is a hack to circumvent what should really be an asynchronous operation.
That being said, the Copy
method is a synchronous operation. The call to OpenFile
will not occur until the call to Copy
completes.
That being said when the call to OpenFile
occurs, if the file does not exist, it is because you copied it to the wrong place, or because some other process is working on the file in question.
回答9:
I thinf Synclock is not good for this case
for explaination, MSDN can help me
The SyncLock statement ensures that multiple threads do not execute the same statements at the same time. When the thread reaches the SyncLock block, it evaluates the expression and maintains this exclusivity until it has a lock on the object that is returned by the expression. This prevents an expression from changing values during the running of several threads, which can give unexpected results from your code.
in my opinion, copy is blocking method, so thread waits until copying is done
can`t be problem in another place?
回答10:
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
回答11:
System.Threading.Thread.Sleep(1000);
来源:https://stackoverflow.com/questions/437396/how-do-i-delay-a-vb-net-program-until-a-file-operation-completes