如何在文件操作完成之前延迟vb.net程序?

时间:2009-01-12 23:10:38

标签: vb.net timing doevents

我有这个:

    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()会纠正这个问题,但事实并非如此。我需要等到文件创建后再打开文件。我怎么能这样做?

11 个答案:

答案 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);