我有一个调用Filewatcher函数的程序,如下所示
Main()
{
watch();
console.Readkey();
}我在末尾有console.readkey,因为我不想让控制台在监视文件更改时显示'Press any key to continue‘。现在,如果检测到更改,则触发另一个函数,该函数执行其工作,并最终再次调用main,该函数再次停止于console.readkey。
在这一点上,我遇到了一些奇怪的问题,比如程序需要两个键输入才能继续。我猜这是因为前面的console.readkey还在等待输入,所以第一个输入在那里,然后第二个输入到第二个console.readkey。
所以,我的问题是,当文件守护程序第一次被触发时,我是否可以通过代码向console.readkey提供一些东西,即等待用户输入?
发布于 2010-09-18 04:23:23
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设置为true,此时它将正常退出。“监视”将不会被连续调用,因为resetEvent将无限期地阻塞。当“工作”完成时(在FileSystemWatcher事件处理程序完成之后),调用resetEvent.Set()。这将导致循环再次重复,重新触发您的手表代码。
它的工作原理是使用一个AutoResetEvent来防止观察者重复地“重新查看”同一个文件。
发布于 2010-09-18 04:34:53
您的控制台应用程序的结构应该更改为使用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发布于 2010-09-18 04:21:55
从this question和这里阅读,我认为你需要重构你的代码,并从WinForms处借用一个消息循环来保持你的程序存活。
添加对System.Windows.Forms.dll的引用。在main方法中,启动您的观察器。然后调用Application.Run()不用担心,你的应用程序仍然可以使用控制台,等等,Run()只会启动一个消息循环,并阻止你的程序继续到main方法的结尾。
然后重构上一个问题中的代码,这样它就不会再次调用Main()。
无论何时想要停止应用程序,都可以调用Application.Exit()。
https://stackoverflow.com/questions/3738731
复制相似问题