Проблема обработки ошибок с FileSystemWatcher - PullRequest
0 голосов
/ 19 января 2020

Начнем с того, что прошло много лет с тех пор, как я много занимался программированием, возможно, около 15 лет, на самом деле VB 6 все еще учили тогда, поэтому я ничего не знаю и могу потеряться в том, что я ' Я читаю, но я пытаюсь. Я использую Visual Studio 2019 и пытаюсь создать приложение VB Windows Forms, которое использует FileSystemWatcher. К сожалению, единственное решение моей проблемы, которое я смог найти, это C#. Я пытался перенести их в свое приложение, но не смог заставить их работать. На самом деле Visual Studio не был доволен тем, что я вставил, и не запустился вообще, возможно, из-за неправильного синтаксиса.

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

Первая проблема заключается в том, что если я создаю пустой файл, код работает чаще всего без проблем, но иногда создаются 2 копии файла. Я мог бы жить с этим, но.

Если я заменю пустой файл на файл большего размера, файл, который он должен копировать, то он может сделать 3 или 4 копии, и в большинстве случаев выдает сообщение, сообщающее, что он не может получить доступ к файлу, потому что он используется. Основная программа также свернута для отображения сообщения об ошибке, которое мне не нужно.

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

Если я сообщаю об ошибке, чтобы отменить то моя программа продолжает и производит только 1 копию файла. Именно это я и хочу.

Вторая проблема заключается в том, что копируемый файл также доступен другой программе в течение короткого периода времени сразу после его изменения, что также приводит к тому, что для него требуется несколько дополнительных копий. made и иногда появляется окно сообщения об ошибке «Используемый файл», и снова основная программа сворачивается для отображения сообщения об ошибке. Изначально у меня были другие фильтры IO.NotifyFilters, которые на самом деле не были необходимыми, и я подумал, что они могли вызывать ошибки, поэтому я их удалил, но это не имело значения.

Самая распространенная ошибка - файл используется, но также было странное «Необработанное исключение произошло в вашем приложении. Не удалось найти файл». Единственная причина, по которой я могу думать об этой ошибке, заключается в том, что файл, возможно, был переименован в файл резервной копии, и новая версия, созданная основной программой в то время, когда моя программа пыталась получить к нему доступ.

С то, что я прочитал, FileSystemWatcher может запускаться несколько раз, и я предполагаю, что именно из-за этого возникают дублирующие копии обеих проблем.

Мне нужно, чтобы мое приложение делало только 1 копию без появления сообщения об ошибке, так как эта программа нуждается работать в фоновом режиме без ввода данных пользователем. По сути, эта часть моего приложения является внешней программой для резервного копирования файла, когда файл изменяется, потому что основная программа часто меняет этот файл, но, похоже, создает резервную копию файла каждые несколько часов.

Следующий код - это то, что я Я использовал, но ничего, что я пробовал, не поймал ошибку, поэтому я удалил обработчик события ошибки. Этот код был скопирован с чего-то похожего и затем C# изменен для моей цели. Я думал, что {} были использованы для C#, а не для VB, но, похоже, он работает, и если я их вытащу, он не будет.

Мой код для FileSystemwatcher: -

            WatchFile = New System.IO.FileSystemWatcher With {
                .Path = Path.GetDirectoryName(strArkMapFileNamePath),
                .Filter = Path.GetFileName(strArkMapFileNamePath),
                .NotifyFilter = IO.NotifyFilters.LastWrite
            }

            ' add the handler to each event
            AddHandler WatchFile.Changed, New FileSystemEventHandler(AddressOf OnLastWrite)

            'Set this property to true to start watching
            WatchFile.EnableRaisingEvents = True

Обработчик события: -

            Private Sub OnLastWrite(sender As Object, e As FileSystemEventArgs)

                'Copy the Save file to a new folder and rename it.
                My.Computer.FileSystem.CopyFile(
                            strArkMapFileNamePath,
                            strBackupPath & "\" & strArkMapFileName & "_" & 
                DateTime.Now.ToString("dd.MM.yyyy_hh.mm.ss") & ".ark",
                            Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
                            Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing)

            End Sub

Я добавил обработчик события ошибки после AddHandler WatchFile.Changed, New FileSystemEventHandler (AddressOf OnLastWrite), но это ничего не сделало.

Я пытался добавьте оператор ошибки перед конечной подпрограммой, и это тоже ничего не сделало, я полагаю, потому что Microsoft.VisualBasi c .FileIO. UIOption.OnlyErrorDialogs, сначала обнаружил ошибку.

Я расстроился и попытался добавить оператор перед Microsoft.VisualBasi c .FileIO.UIOption.OnlyErrorDialogs, но мне это не понравилось, и я не сделал Я не ожидаю, что это сработает.

Так как мне перехватить ошибки до того, как FileSystemWatcher отреагирует на ошибку?

Я не знаю, что я делаю неправильно, поэтому любая помощь будет оценена. Кроме того, если кто-нибудь может предложить код для того, что мне нужно сделать, это может быть код для Windows приложения Forms, потому что мне не очень повезло в преобразовании C# или чего-либо еще.

Редактировать Я заменил My.Computer.FileSystem.CopyFile на метод File.Copy, как предложено, и добавил несколько дополнительных битов.

Private Sub OnLastWrite (отправитель как объект, e как FileSystemEventArgs )

    'Verify that source file exists
    If File.Exists(strArkMapFileNamePath) Then

        'Copy the Save file to a new folder and rename it.
        Dim i As Integer

        For i = 0 To 3

            Try
                ' Overwrite the destination file if it already exists.
                File.Copy(strArkMapFileNamePath, strBackupPath & "\" & strArkMapFileName & "_" & DateTime.Now.ToString("dd.MM.yyyy_hh.mm.ss") & ".ark", True)
                i = 3

                ' Catch exception if the file was already copied.
            Catch copyError As IOException

                'If copy failed reset counter
                i += 1

            End Try

        Next

    End If

End Sub

Хотя это не требуется, поскольку это делается до того, как FileSystemWatcher включен, я добавил оператор If, чтобы проверить, существуют ли файлы, прежде чем пытаться скопировать файл.

Я не совсем доволен l oop, но я знаю, что в нормальных условиях он не будет бесконечным l oop.

Есть ли способ просто поймать специфику c ошибки, с которыми мне нужно было бы справиться, или все будет в порядке, как оно есть?

Мне, вероятно, все еще нужно разобраться, как остановить FileSystemWatcher от отправки более 1 события o r как-то заставляет несколько событий отображаться как 1.

Оператор If был последним, что я добавил, и по какой-то причине теперь программа, похоже, делает только 1 копию и выглядит быстрее.

Другая внешняя программа, которая обращается к копируемому файлу, должна реагировать медленнее, чем моя программа, потому что теперь она отображает сообщение о том, что она ждет, пока моя программа закончит копирование файла.

Моя программа теперь работает так, как была предполагалось, но я считаю, что это всего лишь вопрос времени, а не правильного кода.

...