Reputation: 42450
I have a program that calls a Filewatcher function, like this
Main()
{
watch();
console.Readkey();
}
I have the console.readkey at the end because I don't want the console to display 'Press any key to continue' while the file is being watched for changes. Now, if a change is detected, another function gets triggered off, which does its thing, and eventually calls main again, which once again stops at console.readkey.
At this point, I am experiencing some weird problems like the program requires two key inputs to continue. I'm guessing thats because the console.readkey from before is still waiting for an input, so the first input goes there, and then the second input goes to the second console.readkey.
So, my question is, the first time when the filewatcher gets triggered, can i, via code, feed something to the console.readkey, thats waiting for a user input?
Upvotes: 0
Views: 2896
Reputation: 41
The structure of your Console application should be changed to use a WaitHandle and Ctrl+C to exit the program. The basic structure of such a program is shown below. It should be trivial to convert to 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
Upvotes: 1
Reputation: 564891
Console.ReadKey
will block the program until you press a key (at which point it will read that and return).
It sounds like you, in this situation, need to change your logic to just loop indefinitely (or until some other condition is reached). Instead of using Console.ReadKey
to prevent the application from ending, you should consider re-writing it like:
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...
}
This will make the program run "forever", until you set exitProgram
to true, at which point it will exit normally. The "watch" will not get called continually, since resetEvent
will block indefinitely. When your "work" finishes (after the FileSystemWatcher event handler completes), call resetEvent.Set()
. This will cause the loop to repeat one more time, re-triggering your watch code.
It works by using an AutoResetEvent to prevent the watcher from "rewatching" the same file repeatedly.
Upvotes: 1
Reputation: 24232
Reading from this question and here, I think you need to refactor your code and borrow a message loop from Winforms to keep your program alive.
Add a reference to System.Windows.Forms.dll
. In your main method, start your watcher. Then call Application.Run()
Don't worry, your app can still use the console, etc, Run()
will just start a message loop and prevent your program continuing to the end of the main method.
Then refactor your code from the previous question so it doesn't call Main()
again.
Whenever you want to stop your application, call Application.Exit()
.
Upvotes: 0