2017-09-23 64 views
8

我正在創建一個創建隨機文件的簡單函數。爲了線程安全,它會在重試循環中創建文件,如果文件存在,它會再次嘗試。.NET標準是否在其支持的每個平臺上規範HResult值?

while (true) 
{ 
    fileName = NewTempFileName(prefix, suffix, directory); 

    if (File.Exists(fileName)) 
    { 
     continue; 
    } 

    try 
    { 
     // Create the file, and close it immediately 
     using (var stream = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read)) 
     { 
      break; 
     } 
    } 
    catch (IOException e) 
    { 
     // If the error was because the file exists, try again 
     if ((e.HResult & 0xFFFF) == 0x00000050) 
     { 
      continue; 
     } 

     // else rethrow it 
     throw; 
    } 
} 

根據MSDN,產生HResult值從COM這似乎表明它只能在Windows工作所得,並specifically lists them as "Win32 codes"。但是這是在一個以.NET標準爲目標的庫中,理想情況下它應該在every platform .NET Standard supports上運行。

我想知道的是我是否可以依靠上述方法使用來自HResult的值來實現跨平臺? documentation目前尚不清楚。

如果不是,我該如何確定在其他平臺上期望的HResult值?

注:有一個類似的問題Does .NET define common HRESULT values?,但有人問之前.NET標準(和.NET跨平臺支持)的存在,所以我不能依賴於回答這個目的。

現在,我們的代碼庫只使用:

  1. 0x00000020 - ERROR_SHARING_VIOLATION
  2. 0x00000021 - ERROR_LOCK_VIOLATION
  3. 0x00000050 - ERROR_FILE_EXISTS

我們針對.NET標準1.5。

注:雖然接受的答案的確滿足了我在這裏問,我有一個後續問題How do I make catching generic IOExceptions reliably portable across platforms?

+0

我想你必須要更具體的瞭解要依靠情景或特定錯誤代碼。有很多地方都列出使用了預定義的代碼(你可以在CoreCLR和fullfx參考源代碼中搜索'hresults.cs'),並且在某些情況下還有規範化函數[就像這個文件錯誤一樣](https://github.com/dotnet /coreclr/blob/5c07c5aa98f8a088bf25099f1ab2d38b59ea5478/src/pal/src/file/file.cpp#L184-L194)。 –

+0

謝謝馬丁。我添加了我目前感興趣的3個錯誤。雖然有點希望得到更一般的答案。通常,我們只對文件IO錯誤感興趣。 – NightOwl888

+0

您可能想鏈接到[本文檔](https://docs.microsoft.com/zh-cn/dotnet/api/system.exception.hresult?view=netstandard-1.5)而不是msdn,因爲它是官方.net標準1.5 API文檔。 (相當肯定它是MSDN的複製和粘貼,但很好指向正確的位置) –

回答

7

Exception.HResult值不跨平臺標準化。

對於I/O錯誤,.NET Core將返回特定於平臺的錯誤代碼作爲HResult。在你的例子中已經存在的文件HResult屬性的值在Linux上將爲17,並且對於其他Unix系統它可能是不同的值。

是IO錯誤映射到Unix上的異常相關的代碼是在這裏:https://github.com/dotnet/corefx/blob/master/src/Common/src/Interop/Unix/Interop.IOErrors.cs

+0

謝謝。不幸的是,您提供的鏈接僅顯示代碼,但不顯示提供值的資源文件。目錄中似乎沒有其他平臺的相應文件。我是否會擺脫這一點,上述方法不可靠?或者有什麼方法可以獲得我需要的所有平臺的所有價值?請注意,我只需要.NET Standard 1.5支持的每個平臺的3個錯誤。 – NightOwl888

+0

這種方法不能做到可靠便攜。在這種情況下,HResult是底層操作系統返回的。它可以在Linux,macOS,FreeBSD,...之間不同。我將編輯帖子以說清楚。 –

相關問題