我々は、CLRで非常に重要な違いに注意を払うを「異常」で述べたように。実行時例外によって管理される完全な実装メカニズムを提供する、のtry / catch /最後にアプリケーションにさらされて、そのようなC#などがあります。自分自身の使用のためのランタイム例外があります。ほとんどのランタイム開発者はめったに実装する方法を考えると、管理例外モデルを公開する必要はありません。しかし、開発者が知っておくべき各ランタイムは、例外のCLRの実装を使用する方法です。区別を維持するためには、スローと呼ばれるプログラムをホストし、キャッチします管理例外、およびエラー処理が呼ばれる自分自身の使用に実行されます異常な内部CLRを。この記事では、内部CLR例外に焦点を当てています。
便利例外?
ほぼすべての場所で異常が使用されてきました。最も有用なのは、明示的に記述したコードへの必要性がそれをキャッチしたり、例外と優雅ハンドル例外をスローするため、異常を投げたりキャッチ機能する場所です。関数自体が例外をスローしない場合であっても、例外をスロー関数を呼び出すことも可能です。例外がスローされたときに関数は、通常の動作でなければなりませんように。賢明な使用のサポート(保有者)は大幅にこのようなコードを書くことが正しいです簡素化することができます。
なぜ内部CLR例外は異なっていますか?
CLR内部のC ++の例外のような異常はなく、かなり。CLRは、Mac OSX、BSDと同様にWindowsでコンパイルすることができます。オペレーティングシステムとコンパイラの違いは、私たちだけではなく、標準C ++のtry / catchを使用することができます。さらに、異常な内部CLRも「ついに」などの機能を提供し、マネージコードに似た「障害」。
書き込み例外処理コードにいくつかの簡単なマクロを介するなど、標準C ++のように。
例外をキャッチ
EX_TRY
基本的なマクロは次のように使用EX_TRY / EX_CATCH / EX_END_CATCH、:
EX_TRY // 例外をスローする可能性のある関数を呼び出す )バー(; EX_CATCH // ここでは、エラーが発生した m_finalDisposition = terminallyHopeless; EX_END_CATCH(RethrowTransientExceptions)
EX_TRYマクロはずっとC ++には、さらに括弧を追加することを除いて、「してみてください」のように、tryブロックを導入することです:「{」
EX_CATCH
EX_CATCHマクロは、tryブロックを終了し、中括弧を追加します。「}」、およびcatchブロックが始まります。EX_TRY類似したで、それはまた、catchブロックを開始するためにブレースを追加しました。
C ++ここで例外とは大きな違いがある:CLRの開発者は、どのようなキャッチをクリアしないでください。実際には、これらのマクロは、非C ++例外や管理の例外のものと同様のAVキャプチャが含まれます。あなたが唯一のコードのブロックまたは異常の割合をキャプチャする必要がある場合、それはキャプチャし、異常を調べる必要があり、その後、例外はすべて再び無関係スローされます。
再び、あなたは何をキャプチャすることEX_CATCHマクロを指定する必要があります。これは、必要性の機能ではないかもしれません。次の2つの章では、例外が捕獲すべきではありませんどのように処理するかについて説明します。
GET_EXCEPTION()&GET_THROWABLE()
CLR開発者は事をキャプチャする場合は、その後、彼は何をすべきかを決定しなければなりませんか?ニーズに応じて、いくつかのオプションがあります。
まず、キャッチ(C ++)例外は、Exceptionクラスのクラスのグローバルインスタンスから継承されているかに関係なく。明らかに、いくつかの継承されたクラスの、などのOutOfMemoryExceptionなど。その他は、EETypeLoadExceptionなど一部の地域に関連しています。このようCLRException(OBJECTHANDLEが例外管理視野点を含むもの)、またはHRException(HRESULTパッケージ)としても、単純なパッケージシステム異常、一部のクラス。オリジナルは、Exceptionから継承する例外ではない場合、マクロはパッケージになります。(すべての例外はシステムであり、よく知られているが付属していますことに注意してください)。
第二に、各内部CLRのHRESULT値が関連付けられた例外を有します。時には、COMオブジェクトから値としてHRException等が挙げられるが、内部例外とWin32 APIのエラー値はHRESULT値を持っています。
最後に、ほぼすべての内部CLR例外が発生した可能性が高い他の側マネージコードに渡すされ、CLR例外は彼らのホスティング対応した内部の異常を持っています。管理の例外を作成する必要はありませんが、それを取得する方法は常にあります。
だから、CLRの開発者はどのように例外を分類するには?
一般的な方法は、異常に関連付けられているHRESULT値によって分類され、非常に単純な方法値が存在しています。
HRESULTのHR = GET_EXCEPTION() - > GetHR();
管理例外オブジェクトを対応詳細については、より便利な方法です。例外は即時またはが、後の処理のために捕獲することかどうか、マネージコードに渡される場合は、すべてこの管理対象オブジェクトを必要としています。また、この例外オブジェクトを使用すると、従来の方法を使用することができますので、ホストされたobjectrefに言及している、また、非常に簡単に読むことです:
objectrefにスロー可能= NULL; GCPROTECT_BEGIN(スロー可能)。 // 。。。 EX_TRY // 。。。投げるかもしれない何かを EX_CATCH スロー可能 = GET_THROWABLE(); EX_END_CATCH(RethrowTransientExceptions) // 。。。スロー可能と何かを )(GCPROTECT_END
例外* PEX = GET_EXCEPTION(); もし(pEx-> ISTYPE(CLRException ::メソッドGetType())){ / * ... * / }
例外が供給(またはから継承)CLRExceptionできるかどうか。
EX_END_CATCH(RethrowTransientExceptions)
上記の例では、「RethrowTransientExceptionsは」マクロ引数EX_END_CATCHであり、それは3つの定義済みマクロであり、とみなすことができる「異常人格。」ここではこれらのマクロの説明は次のとおりです。
- SwallowAllExceptions:命名は独創的に簡単です。名前が示すように、それは任意のオブジェクトを巻き込みます。明らかに、通常は正しいアプローチ。
- RethrowTerminalExceptions:より良い名前は、マクロの役割である「RethrowThreadAbort」、である必要があります。
- RethrowTransientExceptions:再試行の異常が他の環境で発生していない可能性がある場合、異常の最高の定義は「一時的」。以下は、一時的な例外です。
- COR_E_THREADABORTED
- COR_E_THREADINTERRUPTED
- COR_E_THREADSTOP
- COR_E_APPDOMAINUNLOADED
- E_OUTOFMEMORY
- HRESULT_FROM_WIN32(ERROR_COMMITMENT_LIMIT)
- HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY)
- (HRESULT)STATUS_NO_MEMORY
- COR_E_STACKOVERFLOW
- MSEE_E_ASSEMBLYLOADINPROGRESS
CLRの開発者は、疑わしい場合には、一般的に使用する必要がありますRethrowTransientExceptionsを。
しかし、いずれにしても、書き込みEX_END_CATCHの開発者は、例外のキャッチを考慮し、のみ例外をキャッチする必要があります。また、このマクロキャプチャのすべてのものではなく、例外をキャッチする唯一の方法は、それを再びスローされますので。
EX_CATCH / EX_END_CATCHブロックが異常正しく分類し、必要なときに再スローした場合、それが再スローされた方法を有するマクロSwallowAllExceptionsを伝えることです。
EX_CATCH_HRESULT
時々必要性は、特にCOMのコードに対して、HRESULT値に対応する異常です。これらのケースでは、マクロブロックEX_CATCHを書くよりもずっと簡単EX_CATCH_HRESULTを使用しています。次のように一般的なコードの断片です。
HRESULTの時間。 EX_TRY // コード EX_CATCH_HRESULT(時間) 戻り時間。
しかし、非常に魅力的であるが、常に正確ではありません。EX_CATCH_HRESULTはHRESULT保存すべての例外をキャッチして、元の例外を捨てます。したがって、負け異常行動しない限り、そうでない場合EX_CATCH_HRESULT、非常に適切な必要性の関数ではありません。
EX_RETHROW
上述したように、例外マクロキャッチすべての例外、指定された例外をキャッチする唯一の方法は、すべての例外をキャッチすることであり、次いで他の例外に加えて撮影するもう一度スローされます。したがって、例外は、捕捉処理した後、結果が捕捉されるべきではない、それが再スローされるかもしれないということである場合。EX_RETHROWマクロは同じ例外をスローするために使用されます。
著者:李ミン
リンクします。https://www.jianshu.com/p/9b3d348c292d
出典:ジェーンの本。