2011-05-31 156 views
13

我正在寫一個c#程序讓我知道何時添加或刪除了一個文件。我在我的Windows 7機器上運行它並在我們的網絡上觀看FTP服務器。FileSystemWatcher停止捕獲事件

它工作正常,但會突然停止捕捉任何事件。我猜測它可能會失去與服務器的連接,或者網絡出現故障。

我該如何處理代碼中的這種情況。是否有一些例外我可以觀察並嘗試重新啓動FileSystemWatcher對象。

任何建議和代碼示例將不勝感激。

+0

因此,如果該文件的1KB已經上傳,你怎麼知道的傳輸是否已經完成?我認爲你需要在這裏重新考慮你的方法。 – leppie 2011-05-31 09:19:17

+0

在使用FileSystemWatcher讀取創建的文件時,查看有關異常的此問題http://stackoverflow.com/questions/699538/file-access-error-with-filesystemwatcher-when-multiple-files-are-added-toa-a- direc – 2011-05-31 09:26:21

+0

當文件被創建或刪除時,捕獲工作正常。我只需要知道如何從丟失的連接或網絡故障中恢復。 FileSystemWatcher對象上是否存在任何類型的異常? – Paul 2011-05-31 23:51:59

回答

10

上一個答案沒有完全解決它,我不得不重置觀察者,而不僅僅是打開和關閉它。 我用FileSystemWatcher的一個窗口服務

void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e) 
{ 
    int iMaxAttempts = 120; 
    int iTimeOut = 30000; 
    int i = 0; 
    while ((!Directory.Exists(source.Path) || source.EnableRaisingEvents == false) && i < iMaxAttempts) 
    { 
     i += 1; 
     try 
     { 
      source.EnableRaisingEvents = false; 
      if (!Directory.Exists(source.Path)) 
      { 
       MyEventLog.WriteEntry("Directory Inaccessible " + source.Path + " at " + DateTime.Now.ToString("HH:mm:ss")); 
       System.Threading.Thread.Sleep(iTimeOut); 
      } 
      else 
      { 
       // ReInitialize the Component 
       source.Dispose(); 
       source = null; 
       source = new System.IO.FileSystemWatcher(); 
       ((System.ComponentModel.ISupportInitialize)(source)).BeginInit(); 
       source.EnableRaisingEvents = true; 
       source.Filter = "*.tif"; 
       source.Path = @"\\server\dir"; 
       source.NotifyFilter = System.IO.NotifyFilters.FileName; 
       source.Created += new System.IO.FileSystemEventHandler(fswCatchImages_Changed); 
       source.Renamed += new System.IO.RenamedEventHandler(fswCatchImages_Renamed); 
       source.Error += new ErrorEventHandler(OnError); 
       ((System.ComponentModel.ISupportInitialize)(source)).EndInit(); 
       MyEventLog.WriteEntry("Try to Restart RaisingEvents Watcher at " + DateTime.Now.ToString("HH:mm:ss")); 
      } 
     } 
     catch (Exception error) 
     { 
      MyEventLog.WriteEntry("Error trying Restart Service " + error.StackTrace + " at " + DateTime.Now.ToString("HH:mm:ss")); 
      source.EnableRaisingEvents = false; 
      System.Threading.Thread.Sleep(iTimeOut); 
     } 
    } 
} 
+0

這似乎保持循環並重新創建文件系統監視器,即使它在某些時候是成功的。在「成功」循環中不應該有中斷嗎? – Matt 2016-04-20 20:37:54

+0

@Matt它應該打破1)路徑存在(可訪問)和b)EnableRaisingEvents == true。 – 2017-10-13 08:56:23

16

我需要添加一個錯誤處理程序FileSystemWatcher的

fileSystemWatcher.Error += new ErrorEventHandler(OnError); 

然後添加以下代碼:

private void OnError(object source, ErrorEventArgs e) 
{ 
    if (e.GetException().GetType() == typeof(InternalBufferOverflowException)) 
    { 
     txtResults.Text += "Error: File System Watcher internal buffer overflow at " + DateTime.Now + "\r\n"; 
    } 
    else 
    { 
     txtResults.Text += "Error: Watched directory not accessible at " + DateTime.Now + "\r\n"; 
    } 
    NotAccessibleError(fileSystemWatcher ,e); 
} 

這是我如何重置SystemFileWatcher對象:

static void NotAccessibleError(FileSystemWatcher source, ErrorEventArgs e) 
    { 
     source.EnableRaisingEvents = false; 
     int iMaxAttempts = 120; 
     int iTimeOut = 30000; 
     int i = 0; 
     while (source.EnableRaisingEvents == false && i < iMaxAttempts) 
     { 
      i += 1; 
      try 
      { 
       source.EnableRaisingEvents = true; 
      } 
      catch 
      { 
       source.EnableRaisingEvents = false; 
       System.Threading.Thread.Sleep(iTimeOut); 
      } 
     } 

    } 

我認爲這段代碼應該做我想做的事情。

+0

如果這確實解決了問題,您應該將其標記爲答案。對於什麼是值得的,拋出的異常是什麼? – 2011-06-02 01:33:52

+0

Chris,其實我並不關心什麼是異常,我只是想確保FileSystemWatcher對象重新啓動。 – Paul 2011-06-02 11:45:50