Как отложить выполнение программы vb.net до завершения файловой операции? - PullRequest
3 голосов
/ 13 января 2009

У меня есть это:

    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 ]

3 голосов
/ 13 января 2009

Я не очень много знаю 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 голос
/ 22 июля 2014

Это некрасиво, но у меня это работает

 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 
1 голос
/ 02 января 2011

Используйте FileSystemWatcher, чтобы предупредить вас, когда файл создан. Без петель.

https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6165137.html

1 голос
/ 13 января 2009

В идеале вы должны выполнить копирование в отдельном потоке, который информирует основной поток GUI, когда это будет сделано, чтобы он мог затем выполнить открытие посредством вызова Invoke.

0 голосов
/ 09 марта 2010
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 
0 голосов
/ 13 января 2009

Я думаю, что Synclock не подходит для этого случая

для объяснения, MSDN может помочь мне

Оператор SyncLock гарантирует, что несколько потоков не будут выполнять одни и те же операторы одновременно. Когда поток достигает блока SyncLock, он оценивает выражение и поддерживает эту исключительность до тех пор, пока не получит блокировку объекта, возвращаемого выражением. Это не позволяет выражению изменять значения во время работы нескольких потоков, что может дать неожиданные результаты из вашего кода.

по моему мнению, копирование является методом блокировки, поэтому поток ожидает, пока копирование не будет завершено

не может быть проблемой в другом месте?

0 голосов
/ 13 января 2009

Во-первых, вы не должны никуда звонить DoEvents. По большей части, когда это используется, это хак, чтобы обойти то, что действительно должно быть асинхронной операцией.

При этом метод Copy является синхронной операцией. Вызов OpenFile не будет выполнен до тех пор, пока не завершится вызов Copy.

То, что говорится, когда происходит вызов OpenFile, если файл не существует, это потому, что вы скопировали его в неправильное место или потому, что какой-то другой процесс работает с данным файлом.

0 голосов
/ 13 января 2009

В дополнение к ответу Тома, не лучше ли поставить Application.DoEvents (), а не заставлять поток спать?

0 голосов
/ 13 января 2009

Это не совсем то, для чего используется Doevents. Чаще всего он используется для очистки очереди сообщений пользовательского интерфейса (чтобы пользовательский интерфейс имел некоторое время ЦП для обновления). Это немного сложнее, чем я описываю, но дело не в этом, поэтому я продолжу.

Попробуйте создать критическую секцию блока кода:

SyncLock Me
  System.IO.File.Copy(myFile, "c:\" & myTemp)
  Application.DoEvents()
End SyncLock

OpenFile(myTemp)
0 голосов
/ 13 января 2009

Это немного глупо, но должно работать.

Do Until (System.IO.File.Exists("C:\" & myTemp))
    Threading.Thread.Sleep(1)
Loop
...