문제

짧은 이야기 : COM inproc-server (dll)와 함께 작동하는 C # 응용 프로그램에서 "0x80010100 : System call failed"예외가 발생하고 디버그 모드에서도 ContextSwitchDeadlock 예외가 발생합니다.

이제 자세히 알아보기 :

1) C # 앱이 STA를 초기화하고 COM 개체 ( "Apartment"로 등록됨)를 생성합니다. 그런 다음 연결 지점을 구독하고 개체 작업을 시작합니다.

2) 어떤 단계에서 COM 개체는 많은 이벤트를 생성하여 동일한 아파트에서 생성되는 매우 큰 COM 개체 컬렉션을 인수로 전달합니다.

3) C # 측의 이벤트 처리기는 위의 컬렉션을 처리하며 때때로 개체의 일부 메서드를 호출합니다. 어떤 단계에서 후자의 호출은 위의 예외와 함께 실패하기 시작합니다.

COM 측에서 아파트는 winproc이 다음과 같은 숨겨진 창을 사용합니다. 라코 디스

이벤트는 COM 서버의 다른 부분에서이 창에 게시됩니다. 라코 디스

이벤트는 실제 매개 변수와 결합 된 표준 ATL CP 구현이며 다음과 같이 요약됩니다. 라코 디스

C #에서 핸들러는 다음과 같습니다. 라코 디스

==================

그렇다면, 아파트의 메시지 대기열이 전달하려는 이벤트로 너무로드되어 있기 때문에 위의 문제가 발생할 수 있습니까? 아니면 메시지 루프를 완전히 차단하여 이러한 동작을 유발해야합니까?

메시지 대기열에 "onEvent"호출로 평가되는 2 개의 순차적 이벤트가 있다고 가정합니다. 첫 번째는 C # 관리 코드를 입력하여 동일한 아파트에있는 비 관리 코드를 다시 입력하려고 시도합니다. 일반적으로 이것은 허용되며 우리는 이것을 많이합니다. 언제, 어떤 상황에서 실패 할 수 있습니까?

감사합니다.

도움이 되었습니까?

해결책

다음과 같은 경우 여러 아파트에서도 작동합니다.

  • 스레드 중 하나만 네트워크 트래픽, 타이머, 게시 된 메시지 등과 같은 외부 이벤트에 응답합니다.
  • 다른 스레드는 COM 요청 만 처리합니다 (처리 중에 주 스레드로 콜백하더라도).

    그리고

    • 두 스레드 큐가 가득 차지 않아 COM이 스레드와 통신 할 수 없습니다.

      첫 번째 : 일부 개체가 다른 개체와 같은 아파트에 있지 않은 것 같습니다. 모든 개체가 STA에서 생성되고 있습니까?

      당신이 설명하는 것은 고전적인 교착 상태입니다. 두 개의 독립적 인 스레드가 서로를 기다리고 있습니다. 이것이 다른 스레드에서 C # 및 COM 측으로 작동하는 해당 디자인에서 발생할 것으로 예상되는 것입니다.

      모든 개체가 동일한 스레드에 있고 숨겨진 창이 해당 스레드에 있으면 괜찮을 것이므로 확인해야한다고 생각합니다. (분명히 여기에는 COM 측에서 생성하여 C # 측으로 전달되는 다른 모든 개체가 포함됩니다.)

      디버거에서 "일시 중지"를 누르고 각 스레드에있는 코드를 확인하여 디버깅을 시도 할 수 있습니다 (RPCRT * .DLL이 표시되면 프록시를보고 있음을 의미합니다). 또는 C # 및 COM 측과 WndProc의 다양한 중요 지점에서 현재 스레드 ID를 DebugPrint 할 수 있습니다. 모두 동일해야합니다.

      두 번째 : 스레드 중 하나만 작업 항목을 생성하고 다른 스레드가 호출에 응답하는 호스트 COM 개체 만 수행하는 경우 (즉, 호출을 생성하지 않는 경우) 여러 스레드에서 작동해야합니다. 타이머, 네트워크 트래픽, 게시 된 메시지 등),이 경우 스레드 대기열이 가득 차서 COM이 호출에 응답 할 수없는 것일 수 있습니다.

      스레드 대기열을 사용하는 대신 중요 섹션으로 보호되는 deque를 사용해야합니다.

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