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 所提供的許多識別碼會指向 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 中,如果您以非同步方式呼叫 unsafe 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。