7

Windows ランタイム タイプで COM エラーが発生した場合、.NET はこのエラーを頻繁に (または常に?)Exceptionインスタンスにラップしているようです。エラー メッセージには、COM HRESULT エラー コードが含まれます。たとえば、AES-CBC で新しい暗号化 API を使用すると、バッファー長が正しくないExceptionと、「指定されたユーザー バッファーは、要求された操作に対して有効ではありません。( Exception from HRESULT: 0x800706F8)」というメッセージが表示されます。

さて、これらの例外をどのように処理すればよいのでしょうか? 例外からコードを読み取って、HRESULTそれがどのような種類の例外であったかを理解する必要がありますか? 従来の .NET では、CryptographicException暗号化エラーを他のエラーと区別するために使用できる を取得していました。

私が理解していないもう 1 つのことは、Microsoft のコード品質規則では、決して例外をスローしてはならず、常に派生型をスローしてはならないということです。その理由は、同様Exceptionに致命的な例外をキャッチするジェネラルを強制的にキャッチする必要がないからOutOfMemoryExceptionです。Exceptio別の規則では、ライブラリで n を決してキャッチしてはならない、というものがあります。ExceptionWindows ストア アプリまたは WinRT ライブラリでキャッチする必要がある場合、これらのポリシーに従うにはどうすればよいでしょうか?

ところで、Clemens Vasters は彼のブログで、致命的な例外をキャッチせずに例外をキャッチする方法を示しています。キャッチExceptionはもはや悪いコードではないと思います。

4

1 に答える 1

4

をキャッチExceptionし、HRESULT をオンにすることで特定のエラーを処理しException、エラーが「予期しない」場合は を再スローすることができます。例えば、

try
{
    // ...
}
catch (Exception ex)
{
    switch (ex->HResult)
    {
    case E_INVALID_USER_BUFFER: // 0x800706f8
        // handle invalid buffer case...
        break;
    default:
        // Unexpected exception; re-throw:
        throw;
    }
}

(無効なバッファを指定すると、実行時エラーというよりも論理エラーのように聞こえることに注意してください。そのため、この特定の例外を本当にキャッチする必要があるかどうか疑問に思います。)

Exceptionまたは、より一般的な解決策は、既知の HRESULT を処理し、より具体的な例外を再スローする関数または関数のセットを作成することです。例えば、

static void HandleKnownExceptions(Action f)
{
    try
    {
        f();
    }
    catch (Exception ex)
    {
        // Detect expected HRESULTs and throw the more-specific exception
        // type for each.
    }
}

これらのアプローチはどちらも、C++ と C# の両方で同じように機能します。

Exceptionプラットフォームまたは他のコンポーネントによって直接スローされるとは限らないことに注意してください。Windows ランタイム ABI レイヤーでは、例外はありません。すべてのエラーは、HRESULT によって ABI 境界を越えて報告されます。CLR は、少数の既知の HRESULT をより具体的な例外の種類に変換しますが、一般的な変換は実行できません。

于 2012-09-25T18:06:20.440 に答える