2010-09-17 4 views
0

У меня есть программа, которая вызывает функцию FileWatcher, как этотподачи на вход Console.ReadKey

Main() 
{ 
    watch();   
    console.Readkey(); 
} 

У меня есть console.readkey в конце, потому что я не хочу консоль для отображения «Нажмите любую чтобы продолжить, пока файл просматривается для изменений. Теперь, если обнаружено изменение, запускается другая функция, которая делает свою вещь, и в итоге снова вызывает main, которая снова останавливается на console.readkey.

На данный момент у меня возникают некоторые странные проблемы, такие как программа требует двух ключевых входов для продолжения. Я предполагаю, что это потому, что console.readkey из before все еще ждет ввода, поэтому первый вход идет туда, а затем второй вход переходит ко второму console.readkey.

Итак, мой вопрос в том, что при первом запуске filewatcher я могу через код передать что-то на console.readkey, ожидающий ввода пользователем?

ответ

1

Console.ReadKey будет блокировать программу, пока вы не нажмете клавишу (в этот момент она будет читать и возвращать).

Похоже, вы в этой ситуации должны изменить свою логику так, чтобы она выполнялась бесконечно (или пока не достигнуто какое-либо другое условие). Вместо того, чтобы использовать Console.ReadKey, чтобы предотвратить приложение от окончания, вы должны рассмотреть переписывание это нравится:

bool exitProgram = false; 
AutoResetEvent resetEvent = new AutoResetEvent(); 

void Main() 
{ 
    while (!exitProgram) 
    { 
     Watch(); // Starts FileSystemWatcher 
     resetEvent.WaitOne(); 
    } 
} 

void WorkFinished() // Call at the end of FileSystemWatcher's event handler 
{ 
    resetEvent.Set(); // This "reschedules" the watcher... 
} 

Это сделает запуск программы «навсегда», до тех пор, пока не будут установлены exitProgram истина, в какой момент он будет выходить как обычно. «Часы» не будут называться постоянно, так как resetEvent будет блокироваться бесконечно. Когда ваша «работа» завершится (после завершения обработчика событий FileSystemWatcher), вызовите resetEvent.Set(). Это заставит цикл повторять еще раз, повторно запуская ваш код часов.

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

+0

Но в этом случае, если я не установлю exitProgram на true, функция watcher будет вызвана бесконечно. Я просто хочу вызвать функцию наблюдателя один раз и позволить ей работать в фоновом режиме, наблюдая за изменениями. Если изменения будут найдены, я остановлю наблюдателя, внесут некоторые изменения в файл и хочу перезапустить наблюдателя. – xbonez

+0

PS - когда функция наблюдателя обнаруживает изменение, он вызывает метод OnChange, который я написал. Я не могу вызвать функцию наблюдателя из этого метода, потому что для внесения необходимых изменений мне нужно снова получить доступ к Main снова. – xbonez

+0

@xbonez: Теперь я понимаю - цикл все еще правильный путь. Я переписал свой ответ, чтобы объяснить, как вы можете выполнить эту работу с помощью цикла + AutoResetEvent. –

0

Чтение от this question и здесь, я думаю, вам нужно реорганизовать свой код и занять цикл сообщений из Winforms, чтобы сохранить вашу программу в живых.

Добавить ссылку на System.Windows.Forms.dll. В своем основном методе запустите своего наблюдателя. Затем звоните Application.Run() Не волнуйтесь, ваше приложение все еще может использовать консоль и т. Д., Run() просто запустит цикл сообщений и не позволит вашей программе продолжить работу до конца основного метода.

Затем отредактируйте свой код из предыдущего вопроса, чтобы он не вызывал Main() еще раз.

Всякий раз, когда вы хотите остановить свое приложение, позвоните по телефону Application.Exit().

+0

Я хочу, чтобы мой код продолжал искать изменения. Поэтому после обнаружения первого изменения и запускается метод OnChange, мне придется снова вызвать функцию метода Filewatcher. Это заставит файловый анализатор снова выглядеть fr, и курсор неизбежно достигнет конца main, снова показывая «Нажмите любую клавишу ...', что я хочу избежать – xbonez

+0

Я не думаю, что это проблема. Я думаю, проблема в том, что OP хочет бесконечный (или, по крайней мере, повторяющийся) цикл, но не знает, как написать один ... –

+0

LOL ... Я знаю, как писать цикл, но я не хочу бесконечно называть функцию watcher. Я хочу называть его один раз, а затем смотреть фоновый поток. Я хочу, чтобы он снова вызывался только в том случае, когда обнаружено изменение файла (потому что, когда обнаружено изменение, я останавливаю наблюдателя, вношу некоторые изменения в файл и хочу снова запустить наблюдателя). – xbonez

1

Структура вашего приложения консоли должна быть изменена для использования WaitHandle и Ctrl + C для выхода из программы. Ниже приведена базовая структура такой программы. Для преобразования в C# должно быть тривиально.

Module modMain 

    Public shutdown As New Threading.ManualResetEvent(False) 

    Public Sub FileCreated(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs) 
     Console.WriteLine("Created: " & e.FullPath) 
    End Sub 

    Public Sub FileChanged(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs) 
     Console.WriteLine("Changed: " & e.FullPath) 
    End Sub 

    Public Sub FileDeleted(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs) 
     Console.WriteLine("Deleted: " & e.FullPath) 
    End Sub 

    Public Sub FileRenamed(ByVal sender As Object, ByVal e As IO.FileSystemEventArgs) 
     Console.WriteLine("Renamed: " & e.FullPath) 
    End Sub 

    Public Sub CancelKeyHandler(ByVal sender As Object, ByVal e As ConsoleCancelEventArgs) 
     e.Cancel = True 
     shutdown.Set() 
    End Sub 

    Sub Main() 

     Dim fsw As New System.IO.FileSystemWatcher 

     Try 

      AddHandler Console.CancelKeyPress, AddressOf CancelKeyHandler 

      ' Do your work here 
      ' press Ctrl+C to exit 
      fsw = New System.IO.FileSystemWatcher("c:\path") 
      fsw.Filter = "*.*" 
      fsw.NotifyFilter = (IO.NotifyFilters.Attributes Or IO.NotifyFilters.CreationTime Or IO.NotifyFilters.DirectoryName Or _ 
           IO.NotifyFilters.FileName Or IO.NotifyFilters.LastAccess Or IO.NotifyFilters.LastWrite Or _ 
           IO.NotifyFilters.Security Or IO.NotifyFilters.Size) 
      AddHandler fsw.Created, AddressOf FileCreated 
      AddHandler fsw.Changed, AddressOf FileChanged 
      AddHandler fsw.Deleted, AddressOf FileDeleted 
      AddHandler fsw.Renamed, AddressOf FileRenamed 
      fsw.EnableRaisingEvents = True 

      shutdown.WaitOne() 

     Catch ex As Exception 
      Console.WriteLine(ex.ToString()) 
     Finally 
      If fsw IsNot Nothing Then fsw.Dispose() 
     End Try 

    End Sub 

End Module 
+0

Это не показывает, как «перепланировать» FileSystemWatcher, тем не менее, поскольку он будет блокироваться навсегда ... –

+0

FileSystemWatcher работает в своем собственном потоке. Поэтому основной поток должен блокироваться, а FileSystemWatcher отправляет и обрабатывает события. Конечно, FileSystemWatcher можно использовать синхронно с методом WaitForChanged. – Pineapple