문제

.NET에 COM 구성 요소를 작성했으며 모든 방법에서 모든 객체를 잠그려고하면 (관리되지 않는 코드로 인해 COM 구성 요소와 대화 함) 예외가 발생합니다.

나는이 순간에 예외의 정확한 텍스트가 없지만 그다지 도움이되지 않았습니다.

그래서 내 질문은 어떤 상황에서 잠금 (syncobject)이 예외를 던질 것인가? 몇 가지 사실은 다음과 같습니다.

  • syncobject는 null이 아닙니다
  • SyncObject는 아직 잠겨 있지 않았습니다

STA (싱글 스레드 아파트) 또는 MTA (멀티 스레드 아파트)에서 달리는 Callee와 관련이 있습니까?

도움이 되었습니까?

해결책

에서 이 페이지:

모든 잠금 획득은 예외를 던질 수 있습니다. 준비하십시오.

대부분의 자물쇠는 CLR 모니터를 포함하여 잠금 획득이 경합에 직면하면 이벤트를 게으르게 할당합니다. 이 배분은 낮은 자원 조건에서 실패 할 수있어 OOM이 잠금 입구에서 발생하는 OOM을 발생시킵니다. (일반적인 비 블로킹 스핀 잠금 잠금 장치는 OOM과 함께 실패 할 수 없으며, 이로 인해 CERS 내부와 같은 일부 리소스 제약 시나리오에서 사용할 수 있습니다. 마찬가지로 SQL Server와 같은 호스트는 교착 상태 감지를 수행하고 심지어 교착 상태를 깨뜨릴 수 있습니다. Enter 문에서 유래 한 예외를 생성하고 System.runtime.interopservices.comexception으로 나타납니다.

종종 그러한 예외에 따라 할 수있는 일이 많지 않습니다. 그러나 실패를 강력하게 처리 해야하는 신뢰성 및 보안에 민감한 코드는이 경우를 고려해야합니다. 우리는 호스트 교착 상태에 지능적으로 응답 할 수있는 경우를 원했지만 대부분의 라이브러리 코드는 스택의 안전한 지점을 지능적으로 풀어서 작동을 다시 시작하고 재 시도 할 수 없습니다. 전형적인 스택에는 단순히 크로스 라이브러리 교합이 너무 많습니다. 이것이 Tryenter와 함께 시간 초과 기반 모니터 획득이 일반적으로 교착 상태 예방에 나쁜 아이디어 인 이유입니다.

당신이 읽을 수 있듯이, 자원 제한 조건에서 우리는 잠금 (O)가 내부적으로 사용하는 모니터의 ENTER 방법에서 예외를 얻을 수있는 것으로 보인다.

그래서 당신의 솔루션은 스핀 웨이트와 같은 것일까 요?

{
    uint iters = 0;
    while (!cond) {
        if ((++iters % 50) == 0) {
            // Every so often we sleep with a 1ms timeout (see #30 for justification).
            Thread.Sleep(1);
        } else if (Environment.ProcessorCount == 1) {
            // On a single-CPU machine we yield the thread.
            Thread.Sleep(0);
        } else {
            // Issue YIELD instructions to let the other hardware thread move.
            Thread.SpinWait(25);
        }
    }
}

Cond가있을 수있는 곳

private volatile int cond = 0

eg interlocked.compareexchange와 함께 사용되는 곳에서 eg thread.current.managedthreadid 또는 0이 아닌 다른 것?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top