2012-05-18 3 views
2

.NET 응용 프로그램의 스레드에서 만들고 실행중인 COM 개체가 있습니다. 스레드는 단일 스레드 아파트로 표시되며 모든 것이 작동하는 것 같습니다. 내 이해는 이러한 스레드가 주 스레드에서 COM 개체에 액세스하려고하면 해당 개체가 자동으로 마샬링되고 .NET에서 직렬화됩니다. 따라서이 경우에도 모든 것이 안전하고 깨끗하게 처리됩니다. 조금 천천히.이 경우 STA 메시지 루프가 필요합니까?

내 질문에, 일이 잘 작동하는 것처럼 보입니다 만, 이 아닙니다. 내가 만드는 STA 스레드에서 메시지 루프를 펌핑합니다. 가능한 경우 메시지 손실을 피할 수 있습니다 (그리고 가능한 효율 손실도 발생할 수 있습니다).

메시지 루프가 필요한 이유 (주로 도움이되는 Hans Passant에서)에 대한 많은 조언을 읽었으며 메시지 루프가 스레드 A에서 다른 스레드 B가 처리 할 수있는 위치를 제공한다는 점을 이해했습니다. 스레드 A에있는 COM 객체를 마샬링하여 재생할 수 있도록 요청하십시오. 그렇다면 다른 스레드가 스레드 A의 COM 개체에서 아무 것도 요청하지 않는 한 스레드 A는 메시지 루프를 펌핑하지 않아도 안전합니까? 아니면 메시지 루프가 재생 될 수있는 다른 경우가 있습니까?

여기에서 불을 탔나요? 그리고 당신이 화재로 놀고 있다면 당신이 묻는 경우가 있습니까?

+0

이벤트가 있습니까? 재진입 호출로 인해 무한 재귀가 발생하지 않도록 이벤트 처리기를 제어 할 수 있습니까? 게시 메시지는 일반적으로 메시지 펌프가있는 경우이 루프를 끊는 데 사용됩니다. –

+0

나는이 문제와 관련이 없다고 생각한다. 내가 만든 스레드에서 이벤트가 발생하고 아무도 다른 이벤트를보고 있지 않은 이유는 무엇입니까? 내가 사용하고있는 COM 객체는 무엇입니까? 내가 아는 한 그들은 이벤트를 발생시키지 않는다. – user12861

+0

COM 개체의 디자인에 외부 세계에 무슨 일이 일어나는지 알려주는 경우 IConnectionPointContainer와 같은 나가는 이벤트 인터페이스를 구현한다. –

답변

3

STA 계약은 메시지 루프를 펌핑해야합니다. 그러나 예, 펌핑하지 않고 빠져 나갈 수 있습니다. 잘못 될 수있는 두 가지 주요 가지가있다 :

  • 다른 STA 스레드 또는가 완료되지 MTA의 스레드를 포함하여, 다른 아파트에서 인터페이스 방식에 만든 상관 없음 전화. 이것은 프로그램에서 교착 상태처럼 보입니다. 호출은 절대 반환되지 않습니다. 자신의 호출을 아주 잘 제어 할 수는 있지만 COM 구성 요소가 무엇을하는지 모를 수 있습니다. 스레드 자체를 시작할 수도 있습니다. Debug + Windows + Threads를 통해 디버거에서이를 볼 수 있습니다. 디버거를 관리되지 않는 모드로 실행하고 표시되는 모든 스레드를 고려할 수 있는지 확인하십시오. 특히 쉬운 btw.

  • 많은 아파트 스레드 COM 구성 요소는 자신의 필요를 처리하는 메시지 루프가 필요합니다. 그것은 타이머처럼 무해한 것일 수 있습니다. 루프가 없을 때 틱하지 않습니다. 또는 내부적으로 마샬링을 수행 할 수도 있습니다. Spy ++를 사용하고 새 STA 스레드가 소유 한 숨겨진 창이 있는지 확인하십시오. 문제가 발생하면 로그인하십시오. 진단은 잘못 행동 한 구성 요소입니다. 사건을 일으키지 않는 것은 흔한 사고입니다. 서버의 내부에 대해 충분히 모를 때

아무것도 정말 벽에 못 없습니다. 그것에서 지옥을 시험하게 확인하십시오.

+0

항상 통찰력있는 대답. 매우 감사. – user12861

+0

우리는'CDO.Message' COM 객체에 비슷한 문제가 있다고 생각합니다. 그것은 사용자가 MDI 창을 주변에서 격렬하게 움직일 때'Send()'에서 결코 돌아 오지 않았습니다. 아마도 그것은 메시지 대기열에 의존하고 있기 때문에 대기열이 모든 윈도우 이동으로 가득 찼기 때문에 그 안에 메시지를 게시 할 수 없었고 구현은'PostMessage'가 실패했는지 확인하는 것을 잊었습니다. –

1

COM 루프는 메시지 루프없이 마샬링 될 수 있습니다.

STA 스레드가 무언가를 기다리고있을 때 대부분의 경우 보류중인 COM 호출을 자동으로 처리합니다.

Thread.Join에 대한 문서가 동일한 사용자를 대신 호출 많은 다른 기능을 위해 일 Blocks the calling thread [...] while continuing to perform standard COM and SendMessage pumping.

말한다 (CoWaitForMultipleHandles 등), 예를 들어, 스레드가 입출력을 기다리고있을 때

+0

좋은 지적. 조언 해주셔서 감사합니다. – user12861