2010-09-17 86 views
0

我有調用Filewatcher功能的程序,這樣飼料投入Console.ReadKey

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

我在年底console.readkey,因爲我不想顯示「按任意控制檯密鑰繼續「,而文件正在觀看更改。現在,如果檢測到更改,則會觸發另一個函數,這會執行其操作,並最終再次調用main,然後再次在console.readkey處停止。

在這一點上,我遇到喜歡的節目一些奇怪的問題,需要兩個關鍵投入繼續。我猜這是因爲之前的console.readkey仍然在等待輸入,所以第一個輸入到那裏,然後第二個輸入進入第二個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 2010-09-17 20:30:04

+0

PS - 當觀察者函數檢測到一個改變時,它調用我寫的OnChange方法。我無法從該方法本身調用觀察器函數,因爲需要進行必要的更改以重新訪問Main – xbonez 2010-09-17 20:30:57

+0

@xbonez:我現在明白了 - 循環仍然是正確的方法。我重寫了我的答案,以解釋如何使用循環+ AutoResetEvent完成此項工作。 – 2010-09-17 20:47:13

0

this question和這裏,我認爲你需要重構你的代碼,並從Winforms借用一個消息循環,以保持您的程序活着。

增加提及System.Windows.Forms.dll。在你的主要方法中,啓動你的監視器。然後請撥打Application.Run()不要擔心,您的應用仍然可以使用控制檯等,Run()只會啓動一個消息循環,並阻止您的程序繼續到主要方法的結尾。

然後從以前的問題,重構你的代碼,因此不會再打電話Main()

每當你要停止你的應用程序,調用Application.Exit()

+0

我希望我的代碼能夠繼續尋找變化。因此,在檢測到第一次更改並且OnChange方法被觸發後,我必須再次調用Filewatcher方法函數。這將設置filewatcher再次查看fr更改,並且光標將不可避免地到達main的結尾,再次顯示'按任意鍵...'這是我想要避免 – xbonez 2010-09-17 20:24:25

+0

我不認爲這是問題 - 我認爲問題更多的是OP想要一個無限(或至少重複)循環,但不知道如何寫一個... – 2010-09-17 20:24:42

+0

大聲笑...我知道如何編寫循環,但我不想在循環中無限地調用觀察器函數。我想調用它一次,然後讓後臺線程觀看。我只希望在檢測到文件更改的情況下再次調用它(因爲當檢測到更改時,我會停止觀察者,對文件進行一些更改並希望再次啓動觀察器)。 – xbonez 2010-09-17 20:28:30

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,因爲它會永遠阻止... – 2010-09-17 22:25:06

+0

FileSystemWatcher在其自己的線程中運行。因此,主線程應在FileSystemWatcher分派和處理事件時阻塞。當然,FileSystemWatcher可以與'WaitForChanged'方法同步使用。 – Pineapple 2010-09-18 00:02:03