2013-07-03 57 views
0

我正在寫一些代碼來觀看(日誌)文件。我使用Notepad ++來更新文件。
我聽取更改事件,有時文件被鎖定,即使我的文件讀取周圍有lock聲明。
這就像StreamReaderFileStream發佈文件,但操作系統(win8和dotnet4.5.1)鎖定更多時間爲什麼FileSystemWatcher.Changed和StreamReader或FileStream會鎖定文件,即使我鎖定(...){...}它?

我知道更改事件的警告名爲twice,但鎖定語句應該照顧它。我想。到現在。

private static object _fileLock = new Object(); 
.. 
_watch.Changed += new FileSystemEventHandler(watch_Changed); 
.. 
void watch_Changed(object sender, FileSystemEventArgs e) 
{ 
    lock (_fileLock) 
    { 
     using (var sr = new FileStream(_pathAndFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     { 
      // read in file... 
      sr.Close(); 
     } 
    } 
} 
+2

鎖定語句與文件無關。 C#不包含任何文件特定的功能。這太專業了。 – usr

回答

3

你是認真混淆鎖定的想法。 Changed事件處理程序中的語句是您用來防止另一個線程使用共享資源的鎖。我們無法在您的代碼段中看到這樣的資源。

對文件的鎖定是一種完全不同的動物。 FileShare枚舉是相關的,它說明了其他代碼對文件的訪問類型。在另一個進程中包含代碼,這是關鍵字從來沒有的情況。使用FileShare.ReadWrite,您在自己的代碼中非常寬容。它允許任何其他進程讀取和寫入文件。這是你必須擔心的一點,當你讀取文件時另一個進程可以寫入文件時,你的代碼是否還能正常工作?換句話說,你可以在閱讀文件時處理文件數據改變。這是非常罕見的,你必須知道很多其他進程正在用這個文件做什麼。也非常難以測試。

這就足夠介紹真正的問題。 FileSystemWatcher.Change事件被觸發而另一個進程正在寫入文件。爲了能夠在事件處理程序中打開該文件,打開文件的進程必須爲您要求的訪問類型提供共享權限。在你的情況下,它至少必須指定FileShare.Read,以便你擁有FileAccess.Read訪問權限。

永遠不要指望永遠如此。對於編寫文件的程序員來說,一個相當理智的推理是「當我忙於寫文件時,任何其他人都無法正確地讀取此文件」。所以他指定了FileShare.None。 Kaboom在你的代碼中,你無法打開它。

對此你什麼都做不了,那是其他程序員說你不能使它工作。有很高的可能性,他對此完全正確。

您通過閱讀文件後面的來處理此問題。在寫入文件的過程完成後。只要記住文件的路徑,把它放在一個線程安全的隊列中。現在你有一個使用的聲明。使用計時器定期嘗試再次打開文件。

相關問題