CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT
.NET Framework 2.0 版開始引進 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT。 .NET Framework 4 版 會在兩種情況下傳回這個 HRESULT:
挾持分析工具在任意時間強制重設執行緒的暫存器,讓執行緒常式存取不一致狀態的結構時。
分析工具嘗試呼叫資訊性方法時 (此方法會從禁止記憶體回收的回呼方法觸發記憶體回收)。
下列章節討論兩種情況。
劫持分析工具
(這種情況下主要的問題是劫持分析工具,雖然有時候非劫持分析工具可以看到這個 HRESULT)。
在這種情況下,挾持分析工具會隨時強制重設執行緒的暫存器內容,使得該執行緒能夠透過 ICorProfilerInfo 方法,來輸入剖析工具程式碼或重新進入 Common Language Runtime (CLR)。
許多分析 API 提供的 ID 指向 CLR 中的資料結構。 許多 ICorProfilerInfo 呼叫只是讀取資訊從這些資料結構,並將其傳回。 不過,CLR 執行時可能會變更那些結構中的內容,而且可能會使用鎖定來執行這項操作。 假設分析工具挾持執行緒時,CLR 已經持有 (或嘗試取得) 鎖定。 如果執行緒重新進入 CLR,並嘗試取得更多鎖定或檢查已開始進行修改的結構,這些結構可能處於不一致的狀態。 在這種情況下很容易會發生死結和存取違規。
一般來說,當非挾持分析工具在 ICorProfilerCallback 方法內執行程式碼,並以有效的參數呼叫至 ICorProfilerInfo 方法中時,都不應該會有死結或收到存取違規。 例如,ICorProfilerCallback::ClassLoadFinished 方法內執行的分析工具程式碼可呼叫 ICorProfilerInfo2::GetClassIDInfo2 方法,以要求類別的相關資訊。 程式碼可能會收到 CORPROF_E_DATAINCOMPLETE HRESULT,表示資訊不可用,它不會鎖死或收到存取違規。 這個 ICorProfilerInfo 呼叫類別會同步呼叫,因為它們都是透過 ICorProfilerCallback 方法進行的。
不過,執行不在 ICorProfilerCallback 方法內之程式碼的 Managed 執行緒會被視為進行非同步呼叫。 在 .NET Framework 1.0 版中,很難判斷非同步呼叫會發生什麼事。 呼叫可能會鎖死、損毀,或提供不正確的答案。 .NET Framework 2.0 版引進了一些簡單的檢查,可幫助您避免這個問題。 在 .NET Framework 2.0 中,如果您以非同步方式呼叫不安全的 ICorProfilerInfo 函式,就會失敗並出現 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT。
非同步呼叫通常是不安全的。 不過,下列方法非常安全,而且特別支援非同步呼叫:
如需詳細資訊,請參閱 CLR 程式碼剖析 API 部落格中的為什麼我們有 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE (英文) 項目。
觸發記憶體回收
這個情況與執行於回呼方法 (此方法禁止記憶體回收) 內部的分析工具有關 (例如,其中一種 ICorProfilerCallback 方法)。 如果分析工具嘗試呼叫可能會觸發記憶體回收的資訊性方法 (例如在 ICorProfilerInfo 介面上的方法),該資訊性方法失敗並出現 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT。
下表顯示禁止記憶體回收,以及可能觸發記憶體回收之資訊性方法的回呼方法。 如果分析工具在所列的其中一個呼叫方法中執行,並且呼叫所列的其中一個資訊性方法,該資訊性方法會失敗並出現 CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT。
禁止記憶體回收的回呼方法 |
觸發記憶體回收的資訊性方法 |
---|---|