2008-09-16 122 views
7

我們剛剛開始運行一個與FileSystemWatcher有關的Dispose()調用似乎掛起的奇怪問題。這是一段時間沒有任何問題的代碼,但我們只是升級到.NET3.5 SP1,所以我試圖找出是否有其他人看到過這種行爲。下面是創建FileSystemWatcher的代碼:FileSystemWatcher Dispose呼叫掛起

if (this.fileWatcher == null) 
{ 
    this.fileWatcher = new FileSystemWatcher(); 
} 
this.fileWatcher.BeginInit(); 
this.fileWatcher.IncludeSubdirectories = true; 
this.fileWatcher.Path = project.Directory; 
this.fileWatcher.EnableRaisingEvents = true; 
this.fileWatcher.NotifyFilter = NotifyFilters.Attributes; 
this.fileWatcher.Changed += delegate(object s, FileSystemEventArgs args) 
{ 
    FileWatcherFileChanged(args); 
}; 
this.fileWatcher.EndInit(); 

這是正在使用的辦法是更新TreeNode對象的狀態圖像(略作調整,以去除企業的具體信息):

private void FileWatcherFileChanged(FileSystemEventArgs args) 
{ 
    if (this.TreeView != null) 
    { 
     if (this.TreeView.InvokeRequired) 
     { 
     FileWatcherFileChangedCallback d = new FileWatcherFileChangedCallback(FileWatcherFileChanged); 
     this.TreeView.Invoke(d, new object[] 
     { 
     args 
     }); 
     } 
     else 
     { 
     switch (args.ChangeType) 
     { 
      case WatcherChangeTypes.Changed: 
       if (String.CompareOrdinal(this.project.FullName, args.FullPath) == 0) 
       { 
        this.StateImageKey = GetStateImageKey(); 
       } 
       else 
       { 
        projectItemTreeNode.StateImageKey = GetStateImageKey(); 
       } 
       break; 
     } 
     } 
    } 
} 

是還有一些我們錯過的東西,或者這是.NET3.5 SP1的異化?

回答

7

只是一個想法......任何機會在這裏有一個死鎖問題?

你在調用TreeView.Invoke,這是一個阻塞調用。如果文件系統更改發生,就像您單擊導致FileSystemWatcher.Dispose()調用的任何按鈕一樣,則將在後臺線程上調用FileWatcherFileChanged方法並調用TreeView.Invoke,該方法將阻塞,直到表單線程可以處理Invoke請求。但是,表單線程將調用FileSystemWatcher.Dispose(),在處理所有待處理的更改請求之前該線程可能不會返回。

嘗試將.Invoke更改爲.BeginInvoke並查看是否有幫助。這可能有助於指引您朝着正確的方向發展。

當然,它也可能是一個.NET 3.5SP1問題。我只是根據你提供的代碼進行猜測。

1

我們也有這個問題。我們的應用程序在.Net 2.0上運行,但是由VS 2008 SP1編譯。我也安裝了.NET 3.5 SP1。我不知道爲什麼會發生這種情況,因爲此時沒有其他線程正在運行(它在應用程序關閉期間),所以它看起來不像我們這一端的死鎖問題。

+0

如果您使用FileSystemWatcher,則可能使用另一個線程; FileSystemWatcher線程可能被阻塞,試圖在UI線程上調用。 – 2008-09-30 16:41:03

2

Scott,我們偶爾會看到.NET中的control.Invoke問題。嘗試切換到control.BeginInvoke,看看是否有幫助。

這樣做將允許FileSystemWatcher線程立即返回。我懷疑你的問題在某種程度上是control.Invoke阻塞,從而導致FileSystemWatcher在處置時凍結。

+0

這似乎是這種情況和正確的解決方案。我答應喬納森,因爲他是第一個迴應。 – 2008-10-03 19:34:30