CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT
В платформа .NET Framework версии 2.0 появилась CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT. платформа .NET Framework 4 возвращает этот HRESULT в двух сценариях:
Когда профилировщик перехвата принудительно сбрасывает контекст регистра потока в произвольное время, чтобы поток попытается получить доступ к структурам, которые находятся в несогласованном состоянии.
Когда профилировщик пытается вызвать информационный метод, который запускает сборку мусора из метода обратного вызова, запрещающего сборку мусора.
Эти два сценария рассматриваются в следующих разделах.
Перехват профилировщиков
(Этот сценарий в первую очередь связан с перехватом профилировщиков, хотя бывают случаи, когда профилировщики без перехвата могут видеть этот HRESULT.)
В этом сценарии профилировщик перехвата принудительно сбрасывает контекст регистра потока в произвольное время, чтобы поток смог ввести код профилировщика или повторно ввести среду CLR с помощью метода ICorProfilerInfo .
Многие идентификаторы, предоставляемые 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 при асинхронном вызове небезопасной ICorProfilerInfo
функции происходит сбой с CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT.
Как правило, асинхронные вызовы не являются безопасными. Однако следующие методы являются безопасными и, в частности, поддерживают асинхронные вызовы:
Дополнительные сведения см. в записи Почему у нас есть CORPROF_E_UNSUPPORTED_CALL_SEQUENCE в блоге API профилирования CLR.
Активация сборки мусора
В этом сценарии используется профилировщик, выполняющийся внутри метода обратного вызова (например, один из ICorProfilerCallback
методов), который запрещает сборку мусора. Если профилировщик пытается вызвать информационный метод (например, метод в ICorProfilerInfo
интерфейсе), который может вызвать сборку мусора, информационный метод завершается сбоем с CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT.
В следующей таблице показаны методы обратного вызова, которые запрещают сборки мусора, и информационные методы, которые могут активировать сборку мусора. Если профилировщик выполняется внутри одного из перечисленных методов обратного вызова и вызывает один из перечисленных информационных методов, этот информационный метод завершается сбоем с CORPROF_E_UNSUPPORTED_CALL_SEQUENCE HRESULT.