CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT
CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT は .NET Framework バージョン 2.0 で導入されました。 .NET Framework 4 では次の 2 つのシナリオで、この HRESULT を返します。
ハイジャックするプロファイラーが任意のタイミングでスレッドのレジスタ コンテキストを強制的にリセットして、スレッドが不整合な状態にある構造体にアクセスしようとするとき。
プロファイラーが、ガベージ コレクションを禁止するコールバック メソッドからガベージ コレクションをトリガーする情報メソッドを呼び出そうとしたとき。
これら 2 つのシナリオについては、次のセクションで説明します。
プロファイラーのハイジャック
(このシナリオは、主にハイジャックするプロファイラーの問題ですが、ハイジャックしないプロファイラーでこの HRESULT が表示される場合もあります)。
このシナリオでは、ハイジャックするプロファイラーはスレッドのレジスタ コンテキストを任意のタイミングで強制的にリセットして、スレッドがプロファイラー コードに入ったり、ICorProfilerInfo メソッドを通じて共通言語ランタイム (CLR) に再び入ったりできるようにします。
プロファイリング API が提供する ID の多くは、CLR 内のデータ構造を指します。 多くの ICorProfilerInfo
呼び出しでは単純にこれらのデータ構造から情報を読み取って戻します。 ただし、CLR では実行時にこれらの構造内の項目が変更される可能性があり、これを実行するためにロックを使用することもあります。 プロファイラーによってスレッドがハイジャックされたときに、CLR が既にロックを保持している (または取得しようとしている) とします。 スレッドが CLR に再び入り、さらに多くのロックを取得しようとしたり、または変更処理中の構造を検査したりする場合、これらの構造は不整合な状態になる可能性があります。 このような状況では、デッドロックとアクセス違反が簡単に発生します。
一般に、ハイジャックを行わないプロファイラーが ICorProfilerCallback メソッド内でコードを実行し、有効なパラメーターを使用して ICorProfilerInfo
メソッドを呼び出すとき、デッドロックが発生したり、アクセス違反が発生したりすることはありません。 たとえば、ICorProfilerCallback::ClassLoadFinished メソッド内で実行されるプロファイラー コードは、ICorProfilerInfo2::GetClassIDInfo2 メソッドを呼び出すことによって、クラスに関する情報を要求する場合があります。 このコードでは、情報が使用できないことを示す CORPROF_E_DATAINCOMPLETE HRESULT が返される場合があります。 ただし、デッドロックが発生したり、アクセス違反が発生したりすることはありません。 これらの ICorProfilerInfo
の呼び出しは、ICorProfilerCallback
メソッドから作成されるため、同期と見なされます。
ただし、ICorProfilerCallback
メソッドの内部にないコードを実行するマネージド スレッドは、非同期呼び出しを行っていると見なされます。 .NET Framework バージョン 1 では、非同期呼び出しで何が発生する可能性があるかを判断するのは困難でした。 この呼び出しでは、デッドロックやクラッシュ、または無効な回答を返すおそれがありました。 .NET Framework バージョン 2.0 では、この問題を回避するのに役立つ簡単なチェックがいくつか導入されました。 .NET Framework 2.0 では、安全でない ICorProfilerInfo
関数を非同期的に呼び出すと、CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT で失敗します。
一般に、非同期呼び出しは安全ではありません。 ただし、次のメソッドは安全であり、非同期呼び出しを特にサポートしています。
詳細については、CLR プロファイル API ブログの「CORPROF_E_UNSUPPORTED_CALL_SEQUENCE がある理由」という項目を参照してください。
ガベージ コレクションのトリガー
このシナリオでは、ガベージ コレクションを禁止するコールバック メソッド (たとえば、ICorProfilerCallback
メソッドの 1 つ) の内部で実行されているプロファイラーが関与 します。 プロファイラーが、ガベージ コレクションをトリガーする可能性のある情報メソッド (たとえば、ICorProfilerInfo
インターフェイスのメソッド) を呼び出そうとすると、情報メソッドは CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT で失敗します。
次の表は、ガベージ コレクションを禁止するコールバック メソッドと、ガベージ コレクションをトリガーする可能性のある情報メソッドを示しています。 プロファイラーが、一覧表示されているいずれかのコールバック メソッド内で実行され、一覧表示されている情報メソッドの 1 つを呼び出すと、その情報メソッドは CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT で失敗します。
関連項目
.NET