2015-07-05 69 views
0

我在Ubuntu虛擬機上有一個dnx控制檯應用程序,用於監視與主機操作系統(Windows 8.1)共享的文件夾。當Ubuntu VM上的共享文件夾中發生文件更改時,控制檯應用程序會對其進行響應,但在主機上進行文件更改時不會響應。無論如何,它是如何發揮作用的?FileSystemWatcher無法響應虛擬機及其主機共享的文件夾中的文件事件

using System; 
using System.IO; 
public class Program 
{ 
    public static void Main(string[] args) 
    { 
     FileSystemWatcher watcher = new FileSystemWatcher(); 
     watcher.Path = "/media/sf_shared"; 
     watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName; 
     watcher.Changed += new FileSystemEventHandler(Respond); 
     watcher.Created += new FileSystemEventHandler(Respond); 
     watcher.Deleted += new FileSystemEventHandler(Respond); 
     watcher.EnableRaisingEvents = true;   
     Console.ReadKey();   
    } 
    private static void Respond(object source, FileSystemEventArgs e) 
    { 
     Console.WriteLine("Hej"); 
    } 
} 

回答

1

在Linux上,Mono將使用inotify作爲其首選事件發佈後端到FileSystemWatcher類。在你的情況下的問題是,Windows對文件系統的更改不會導致Ubuntu/Linux文件系統發佈事件... Windows到Windows UNC共享路徑確實發佈文件系統事件,但跨平臺文件系統共享'典型'不要......即將Samba嵌入到VM主機中......不是硬性規則,但每個部署的環境都需要測試。

您的情況發生這種情況的唯一方法是一個輪詢系統,mono支持,如果事實上它支持5個不同的後端文件系統事件開箱即用。

您可以強制它使用內置的輪詢方法(文件表對象創建之前做到這一點):

Environment.SetEnvironmentVariable ("MONO_MANAGED_WATCHER", "1"); 

或運行應用程序之前設置環境VAR:

export MONO_MANAGED_WATCHER=1 

買方當心:這是輪詢時的性能問題。這將會導致你的觀察者在750毫秒內定義的內容進行目錄掃描。保持你的觀察者爲一個目錄,沒有子目錄,並且最好是它被過濾到一個非常小的文件子集(一個?),並且如果可能的話,在該目錄中只有一個文件... ...

這被記錄在一一次在單文檔,但我無法再找到它(但它是在源代碼;-):

https://github.com/mono/mono/blob/88d2b9da2a87b4e5c82abaea4e5110188d49601d/mcs/class/System/System.IO/FileSystemWatcher.cs#L115

在線文檔: http://docs.go-mono.com/monodoc.ashx?link=T%3aSystem.IO.FileSystemWatcher

舊文檔註釋(可能是在單聲道的手冊頁?):

「Mono的FileSystemWatcher實現有多個後端。 這是必要的,因爲並非Mono 所支持的所有操作系統都具有提供應用程序預期功能 所需的所有功能。

如果操作系統內核支持觀看目錄(Linux上的inotify ,BSD或OSX上的KEvents),則使用該功能;否則它會回到使用Gamin或FAM庫(這些庫提供API來監視目錄),如果這些功能中沒有一個可用,則Mono將每隔750毫秒輪詢目錄 。

你可以通過執行應用程序之前設置MONO_MANAGED_WATCHER環境變量 強制投票的行爲(而不是使用內核 支持)。這可能對不支持inotify的 文件系統有用,並且仍然需要輪詢到 檢測更改。「

相關問題