我有这个:
Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"
System.IO.File.Copy(myFile, "c:\" & myTemp)
Application.DoEvents()
OpenFile(myTemp)
问题在于,当我调用OpenFile时,它只是调用打开文件的子,它无法找到该文件。这是因为它调用它的速度非常快,以至于程序没有时间在开放之前实际创建文件。
我认为DoEvents()会纠正这个问题,但事实并非如此。我需要等到文件创建后再打开文件。我怎么能这样做?
答案 0 :(得分:3)
我真的不太了解VB.NET,但是不是复制阻塞调用吗?你确定你不只是试图从错误的位置打开文件(或未转义的反斜杠使路径无效)?
这个怎么样?我已经将驱动器号添加到OpenFile中,并且两个地方都没有反斜杠。
Dim myTemp As String
myTemp = System.DateTime.Now().ToString("MMMddyyyy_HHmmss") & ".pdf"
System.IO.File.Copy(myFile, "c:\\" & myTemp)
OpenFile("c:\\" & myTemp)
答案 1 :(得分:1)
理想情况下,您应该在一个单独的线程上执行复制,该线程在完成后通知主GUI线程,然后它可以通过Invoke调用执行打开。
答案 2 :(得分:1)
使用FileSystemWatcher在创建文件时提醒您。没有循环。
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6165137.html
答案 3 :(得分:1)
这很丑,但对我有用
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
答案 4 :(得分:0)
这有点hacky,但它应该有效。
Do Until (System.IO.File.Exists("C:\" & myTemp))
Threading.Thread.Sleep(1)
Loop
答案 5 :(得分:0)
这并不是Doevents的用途。它最常用于让UI消息队列清除(让UI有一些CPU时间来刷新)。它比我描述的要复杂一点,但这不是你问题的重点,所以我会继续前进。
尝试使用此代码块的关键部分:
SyncLock Me
System.IO.File.Copy(myFile, "c:\" & myTemp)
Application.DoEvents()
End SyncLock
OpenFile(myTemp)
答案 6 :(得分:0)
除了Tom的答案之外,最好放一个Application.DoEvents()而不是让线程睡眠?
答案 7 :(得分:0)
首先,您不应该在任何地方调用DoEvents。在大多数情况下,当它被使用时,它是一个黑客,以规避应该真正的异步操作。
话虽这么说,Copy
方法是同步操作。在调用OpenFile
完成之前,不会调用Copy
。
当对OpenFile
的调用发生时,如果该文件不存在,那是因为您将其复制到了错误的位置,或者是因为某些其他进程正在处理相关文件。
答案 8 :(得分:0)
我很简单,对于这种情况,Synclock并不好用
解释,MSDN可以帮助我
SyncLock语句确保多个线程不会同时执行相同的语句。当线程到达SyncLock块时,它会计算表达式并保持此独占性,直到它对表达式返回的对象具有锁定。这可以防止表达式在运行多个线程期间更改值,这可能会从代码中产生意外结果。
在我看来,复制是阻塞方法,所以线程等待复制完成
在另一个地方不是问题吗?
答案 9 :(得分:0)
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
答案 10 :(得分:-1)
System.Threading.Thread.Sleep(1000);