2011-12-08 141 views
11

我公司的代碼庫中包含下面的C#線:使用Directory.Exists當網絡出現故障

bool pathExists = Directory.Exists(path); 

在運行時,串path恰好是該公司的一個文件夾的地址內聯網 - 類似\\company\companyFolder。當我的Windows機器連接到內部網時,這個工作正常。但是,當連接斷開時(如今它所做的那樣),執行上面的行會導致應用程序完全凍結。我只能使用任務管理器關閉應用程序。

當然,在這種情況下,我寧願讓Directory.Exists(path)返回false。有沒有辦法做到這一點?

回答

11

對於這種情況,無法更改Directory.Exists的行爲。在引擎蓋下,它在UI線程上通過網絡發出同步請求。如果網絡連接因爲停機,流量過多等原因而掛起,則會導致UI線程掛起。

您可以做的最好的做法是從後臺線程發出此請求,並在經過一段時間後明確放棄。例如

Func<bool> func =() => Directory.Exists(path); 
Task<bool> task = new Task<bool>(func); 
task.Start(); 
if (task.Wait(100)) { 
    return task.Value; 
} else { 
    // Didn't get an answer back in time be pessimistic and assume it didn't exist 
    return false; 
} 
+3

這可能會輕易吞噬線程池中的所有可用線程,從而導致應用程序內出現更多問題。如果你要做這樣的事情,你需要能夠在超時過後終止操作。 –

+0

@ csharptest.net這是問題,但你不能。 'Directory.Exists'方法不能被超時控制,因爲它本質上是直接下降到本地代碼事件,'Thread.Abort'不會幫助你。 – JaredPar

1

如果一般的網絡連接是你的首要問題,你可以嘗試在此之前測試網絡連通性:

[DllImport("WININET", CharSet = CharSet.Auto)] 
    static extern bool InternetGetConnectedState(ref int lpdwFlags, int dwReserved); 

    public static bool Connected 
    { 
     get 
     { 
      int flags = 0; 
      return InternetGetConnectedState(ref flags, 0); 
     } 
    } 

然後確定路徑是一個UNC路徑,如果返回false網絡處於脫機狀態:

public static bool FolderExists(string directory) 
    { 
     if (new Uri(directory, UriKind.Absolute).IsUnc && !Connected) 
      return false; 
     return System.IO.Directory.Exists(directory); 
    } 

當您嘗試連接的主機處於脫機狀態時,這些都不起作用。在這種情況下,您仍然處於2分鐘的網絡超時狀態。