2017-09-23 2 views
8

Ich erstelle eine einfache Funktion, die eine zufällige Datei erstellt. Um Thread-sicher zu sein, erstellt es die Datei in einer Wiederholungsschleife und wenn die Datei existiert, wird es erneut versucht.Normiert .NET Standard HResult-Werte für jede Plattform, die es unterstützt?

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; 
    } 
} 

Laut MSDN wird der HResult Wert von COM abgeleitet, die es nur auf Windows, um anzuzeigen scheint, wird funktionieren, und es specifically lists them as "Win32 codes". Aber das ist in einer Bibliothek, die .NET Standard zielt und im Idealfall sollte es auf every platform .NET Standard supports arbeiten.

Ich frage mich, ob ich mich auf den obigen Ansatz verlassen kann, der den Wert von HResult verwendet, um plattformübergreifend zu sein? Die documentation ist in diesem Punkt nicht klar.

Wenn nicht, wie ermittle ich, welche HResult-Werte auf anderen Plattformen zu erwarten sind?

HINWEIS: Es gibt eine ähnliche Frage Does .NET define common HRESULT values?, aber es wurde gefragt, bevor .NET Standard (und plattformübergreifende Unterstützung für .NET) existiert, so kann ich nicht für diesen Zweck auf dieser Antwort verlassen.

Vorerst unsere Codebasis verwendet nur:

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

Wir zielen .NET Standard-1.5.

HINWEIS: Während die akzeptierte Antwort nicht erfüllt, was ich hier gefragt, ich habe eine weitere Frage How do I make catching generic IOExceptions reliably portable across platforms?

+0

Ich denke, Sie präziser über das Szenario oder spezifische Fehlercodes, die Sie sich verlassen wollen sein müssen .. Es gibt viele Orte Listen wurden Es werden vordefinierte Codes verwendet (Sie können sowohl im CoreCLR als auch im Fullfx Referenzquellcode nach 'hresults.cs' suchen) und in einigen Fällen gibt es Normalisierungsfunktionen [wie diese für Dateifehler] (https://github.com/dotnet) /coreclr/blob/5c07c5aa98f8a088bf25099f1ab2d38b59ea5478/src/pal/src/file/file.cpp#L184-L194). –

+0

Danke Martin. Ich fügte die 3 Fehler hinzu, die mich derzeit interessieren. War aber irgendwie auf eine allgemeinere Antwort gehofft. Im Allgemeinen sind wir jedoch nur an Datei-IO-Fehlern interessiert. – NightOwl888

+0

Möglicherweise möchten Sie anstelle von msdn eine Verbindung zu [dieser Dokumentation] (https://docs.microsoft.com/en-us/dotnet/api/system.exception.hresult?view=netstandard-1.5) herstellen die offiziellen .net Standard 1.5 API Dokumente. (Ziemlich sicher, dass es ein Kopieren und Einfügen des MSDN ist, aber es ist gut, auf den richtigen Punkt zu zeigen) –

Antwort

7

Exception.HResult Werte sind nicht auf allen Plattformen standardisiert.

Bei E/A-Fehlern gibt .NET Core plattformspezifischen Fehlercode als HResult zurück. Der Wert der HResult-Eigenschaft für die Datei ist in Ihrem Beispiel bereits vorhanden und wird unter Linux auf 17 gesetzt. Für andere Unix-Systeme kann dies ein anderer Wert sein.

Der entsprechende Code, der IO Fehler Ausnahmen auf Unix-Karten ist hier: https://github.com/dotnet/corefx/blob/master/src/Common/src/Interop/Unix/Interop.IOErrors.cs

+0

Danke. Leider zeigt der von Ihnen angegebene Link nur den Code, nicht jedoch die Ressourcendatei, die die Werte bereitstellt. Es scheint keine entsprechende Datei für andere Plattformen in diesem Verzeichnis zu geben. Soll ich davon wegnehmen, dass der obige Ansatz nicht zuverlässig gemacht werden kann? Oder gibt es eine Möglichkeit, alle Werte zu erhalten, die ich für alle Plattformen benötige? Beachten Sie, dass ich nur die 3 Fehler in meiner Frage für jede Plattform, die .NET Standard 1.5 unterstützt, benötigen. – NightOwl888

+0

Dieser Ansatz kann nicht zuverlässig portierbar gemacht werden. HResult ist in diesem Fall, was das zugrunde liegende Betriebssystem zurückgibt. Es kann zwischen Linux, macOS, FreeBSD, ... unterscheiden. Ich werde den Beitrag bearbeiten, um es klarzustellen. –

Verwandte Themen