Sunday 12 March 2017

Gethrforexception Ioexception C #

Die Eigenschaft System. Exception. HResult ist geschützt. Wie kann ich in einer Ausnahme zu sehen und erhalten die HResult ohne Rückgriff auf Reflexion oder andere hässliche Hacks Heres die Situation: Ich möchte ein Backup-Tool, das öffnet und liest Dateien auf einem System zu schreiben. Ich öffne die Datei mit FileAccess. Read und FileShare. ReadWrite, nach dieser Anleitung. Weil ich nicht interessiere mich, wenn die Akte für das Schreiben geöffnet ist, an der Zeit, die ich es las. In einigen Fällen, wenn eine Datei, die ich lese, von einer anderen App geöffnet wird, wirft die System. IO. FileStream. Read () - Methode eine System. IO. IOException, Der Prozess kann nicht auf die Datei zugreifen, da ein anderer Prozess einen Teil der Sperre gesperrt hat Datei. Dies ist Fehler 33. oder ich denke, HResult 0x80070021. BEARBEITEN. Ich glaube, dies kann zurückgegeben werden, wenn ein anderer Prozess aufruft LockFileEx, um einen Bytebereich innerhalb einer Datei zu sperren. Id wie zu pausieren und erneut versuchen, wenn ich diese Fehlermeldung erhalten. Ich denke, dies ist die geeignete Aktion, um hier zu nehmen. Wenn der Sperrvorgang die Bytebereichssperre schnell freigibt, kann ich die Datei lesen. Wie kann ich eine IOException aus diesem Grund unterscheiden, von anderen kann ich an diese Art und Weise denken: private Reflexion - nicht tun wollen. Perf wird stinken. Rufen Sie Exception. ToString () auf und analysieren Sie die Zeichenfolge. Fühlt sich hackig an. Arbeitet nicht in i18n Versionen. Ich mag diese Optionen nicht. Gibt es eine bessere, sauberere Art, die ich gerade durchsucht und gefunden System. Runtime. InteropServices. Marshal. GetHRForException. Wird das wieder eine uint wie 0x80070021Marshal. GetHRForException tut mehr als nur Get-HR-For-Exception Let8217s ersten Start mit Blick auf ein kleines Code-Snippet: Das sieht völlig gut, nicht richtig. Es stellt sich heraus, diese API ist eigentlich schlecht benannt, und es tatsächlich mehr als nur Abrufen der HR aus dem Ausnahmeobjekt. Mit dieser API falsch können Sie einige seltsame Probleme, wie das Auswerfen einer falschen, alten Ausnahme. Also, was bedeutet die API tatsächlich tun Neben der Rückgabe Sie die HRESULT, diese Funktion setzt auch das aktuelle Thread IErrorInfo-Objekt das Ausnahmeobjekt sein. Jeder Thread hat ein assoziertes IErrorInfo COM-Objekt, standardmäßig auf NULL. Dieses IErrorInfo-Objekt repräsentiert den Fehler des letzten COM-API-Aufrufs, der wie die GetLastError () - Win32-API oder errno-C-API ist. Von dem IErrorInfo-Objekt können Sie weitere Informationen wie die Fehlerbeschreibung, Hilfedatei Kontext, etc, erhalten, die Ihnen weitere Informationen über den Fehler. Durch das Setzen des IErrorInfo-Objekts auf das Ausnahmeobjekt (eigentlich auf die IErrorInfo-Implementierung des Ausnahmeobjekts, das von allen verwalteten Objekten freigegeben wird), erzählen Sie im Wesentlichen Ihren COM-Aufrufern, quothey, es gibt einen Fehler, it8217s dieses Ausnahmeobjekt und Sollten Sie etwas über itquot tun, was offensichtlich eine schlechte Idee ist, wenn Sie nur den HR abrufen möchten. In vielen Fällen könnte dies unbemerkt gehen, wenn Ihr COM callercallee IErrorInfo korrekt behandelt. Ich denke, sie folgen dem COM IErrorInfo-Protokoll, die im Grunde sind: 1. Der Anrufer verwenden IErrorInfo aus dem aktuellen Thread beim Aufruf einer COM-Schnittstelle, die explizit sagt, dass ich IErrorInfoquot 2. Die callee (die die COM-Schnittstelle implementiert) sagt, dass sagt QuotI Support IErrorInfoquot, muss IErrorInfo vor der Rückgabe löschen. Dies ist sehr ähnlich zu GetLastError () errno, rechts Wenn dies der Fall ist, würde die falsch eingestellte IErrorInfo in den Thread, würde normalerweise entweder überschrieben werden, durch einige Interface-Implementierung, die IErrorInfo unterstützt oder ignoriert. Jedoch, weil das Protokoll, das ich beschrieben wurde, von jedem COM-Entwickler wirklich nicht sehr gut verstanden wird, I8217ve häufig gesehen Fälle, in denen die COM-Komponente gerade quotsure sagt, stütze ich IErrorInfo auf jedem COM interfacequot und sie don8217t setclear IErrorInfo überhaupt. Und dann würde der Anrufer dieser schlecht implizierten COM-Schnittstelle würde am Ende mit dem IErrorInfo durch GetHRForException Aufruf früher gesetzt und ist zu glauben, dass es einen Fehler. Zum Beispiel betrachten let8217s das folgende Szenario: Einige COM-Komponente A Aufrufe in Code-Code werfen eine Ausnahme, sagen IOException-Code fängt die Ausnahme, und rufen Sie Marshal. GetHRForException, die IErrorInfo auf diese Ausnahme IOException-Code aufruft, in eine andere COM-Komponente B, Aufrufe aufruft In IB. Func IB. Func fehlgeschlagen und zurückgeben einige HR-Fehler-Code, sagen EOUTOFMEMORY CLR sieht die HR-Fehlercode und fragen Sie die COM-Komponente B quotdo Sie unterstützen IErrorInfoquot, und B Antworten quotsure, warum notquot, außer es doesn8217t wirklich unterstützen und Es doesn8217t setclear IErrorInfo CLR abrufen die IErrorInfo, und sieht, dass es sich tatsächlich um eine verwaltete Ausnahme, und wirft die IOException Ausnahme statt OutOfMemoryException. Jetzt könnten Sie sich fragen: Was ist diese API wirklich für den ersten Platz gedacht Es ist tatsächlich in Orten in COM interop verwendet, wo Sie die HRESULT zurückgeben und setzen Sie IErrorInfo selbst. Das tut sich sehr oft 8211 die meisten Menschen wäre glücklich genug, um COM Interop kümmert sich um diesen Teil durch die Umwandlung von Exception in HR und IErrorInfo (die geschieht, um Marshal. GetHRForException aufrufen). So, wenn Sie nicht wirklich wissen, was Sie tun, ist mein Rat, weg von Marshal. GetHRForException zu bleiben. Was, wenn Sie wirklich, wirklich wollen, um nur die HRESULT für eine bestimmte Ausnahme Sie sollten Exception. HResult Eigenschaft verwenden.


No comments:

Post a Comment