簡體   English   中英

FileSystemWatcher - 第二次不觸發事件

[英]FileSystemWatcher - event not firing the second time

我有一個應用程序啟動其他應用程序,然后等待它們創建一個特定的數據文件(它一次監視一個應用程序)。 每次啟動應用程序時,它都會監視要創建的特定文件的特定目錄。 我正在使用FileSystemWatcher執行此操作(將其設置為目錄,然后篩選正確的文件名)。 這是第一次(總是)很好用,但是第二次啟動的應用程序永遠不會觸發事件。 它似乎觸發事件的唯一方法是,如果我在事件處理程序中放置一個斷點,或者如果我在事件處理程序中有一個Thread.Sleep命令。 這對我來說似乎很奇怪......是否有一些我不知道的競爭條件? 這是代碼。 注意我有一個Thread.Sleep(500)。 有了這一行,代碼每次都有效。 沒有它會失敗。 我真的不習慣依賴睡眠命令。 我不確定什么條件會導致不能正常工作。

    public static void watchFiles(string path)
    {
        FileSystemWatcher watcher = new FileSystemWatcher();
        watcher.Path = path;
        watcher.Created += new FileSystemEventHandler(watcher_Handler);
        watcher.EnableRaisingEvents = true;
   }

    public static void watcher_Handler(object sender, FileSystemEventArgs e)
    {
        //Hack - the sleep allows the second and third application to be caught by this event
        Thread.Sleep(500);

        switch (e.ChangeType.ToString())
        {
            case "Changed":
                break;
            case "Deleted":
                break;
            case "Created":
                if (e.Name == "log.dat")
                {
                    parseDataFile();
                    moveHTMLtoLMS();

                }
                break;
            default:
                break;
        }
    }

任何人都知道我為什么需要睡眠(或斷點)才能讓代碼第二次運行?

public static void watchFiles(string path)
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = path;
    watcher.Created += new FileSystemEventHandler(watcher_Handler);
    watcher.EnableRaisingEvents = true;
}

watcher變量在此方法結束時有資格進行垃圾回收。 不要成為局部變量,而是將其作為類級別成員:

private static FileSystemWatcher watcher;

public static void watchFiles(string path)
{
    if (watcher != null)
    {
        watcher.EnableRaisingEvents = false;
        watcher.Created -= new FileSystemEventHandler(watcher_Handler);
    }

    watcher = new FileSystemWatcher();
    watcher.Path = path;
    watcher.Created += new FileSystemEventHandler(watcher_Handler);
    watcher.EnableRaisingEvents = true;
}

根據System.IO.FileSystemWatcher類的文檔:

Windows操作系統會在FileSystemWatcher創建的緩沖區中通知組件文件更改。 如果在短時間內有許多變化,緩沖區可能會溢出。 這會導致組件無法跟蹤目錄中的更改,並且只會提供一攬子通知。 使用InternalBufferSize屬性增加緩沖區的大小是昂貴的,因為它來自無法換出到磁盤的非分頁內存,因此請保持緩沖區盡小但足夠大,以免錯過任何文件更改事件。 要避免緩沖區溢出,請使用NotifyFilter和IncludeSubdirectories屬性,以便過濾掉不需要的更改通知。

可能是事件沒有被足夠快地消耗,並且內部緩沖區不足以處理所有通知。 默認情況下,觀察程序處理FileNameDirectoryNameLastWrite通知,但您只使用創建事件(文件和目錄)。 您的應用程序是否快速連續運行? 我嘗試在應用程序的調用(而不是事件處理程序)之間設置延遲,使用更具體的過濾器(僅使用FileName通知或僅使用Filter屬性監視日志文件),增加內部緩沖區大小或任何組合上述的。 我認為應該解決你的問題。

你只能參加一個“創建”活動。 您還需要收聽所有其他內容 - OnChanged,OnDeleted - http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

編輯:當一個程序已經存在時,大多數程序都不會“創建”文件。 您可以使用FileMon(現在為Process Monitor - http://technet.microsoft.com/en-us/sysinternals/bb896645 )查看每個程序對您的文件執行的操作。

我在這里遇到了完全相同的問題(運行Windows XP)。 你的黑客解決了這個問題。 我想補充一些可能相關的注釋。

在我的例子中,文件名始終是相同的:C:\\ blah.txt被創建,刪除,創建等等。 另外,我正在使用一個技巧隱藏我的應用程序:

Integrator.StartMonitor(); // Start the file monitor!

Form f = new Form();
f.ShowInTaskbar = false;
f.ShowIcon = false;
f.StartPosition = FormStartPosition.Manual; 
f.Location = new Point(-32000, -32000);

f.Show();
f.Hide();

Application.Run();

我的文件監視器工作在調試模式或我添加你的睡眠黑客。 它當然看起來像FileSystemWatcher一個錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM