2015-01-05 13 views
0

내가 그러나 질문 가 지금까지 해결책을 발견하는 온, 내가 아파트 개념 및 이유를 STA 또는 MTA 사용을 이해 생각 개체.STA 또는 MTA는

내 응용 프로그램이 제 3 자 파티 라이브러리의 COM 개체를 사용하는 경우 MultiThreaded-Appartment (MTA)를 사용할 수 있는지 어떻게 알 수 있습니까? 이 경우 , 나는 그 객체는 스레드로부터 안전합니다 경우 아무 생각이 없다, 그래서 난 그냥 안전을 위해, STA와 를 이동해야합니까?

답변

1

STA 또는 MTA 스레드 코드를 특정 COM 인터페이스 포인터를 사용하는 능력은 모든 택시에서이 스레드에서이 포인터를 얻을 여부에 따라 달라집니다. STA (또는 MTA) 스레드에서 포인트를 얻을 수 있다면 다른 아파트로 직접 전달하지 않는다면 추가로 사용하는 것이 좋습니다.

COM 서버가 아파트 유형 불일치 (일반적인 경우 : STA 스레드 및 COM 서버가 "무료"아파트 모델을 사용하여 등록됨)로 인해 포인터를 얻을 수없는 방식으로 등록 된 경우 COM은 포인터를 마샬링하려고 시도합니다. 당신. 마샬링이 성공하면 코드가 포인터를 받고 거기에서부터 시작하는 것이 좋습니다. 그렇지 않으면 오류가 발생하고 다른 아파트에서 동일한 작업을 수행하려는 시도가 성공합니다. 기본적으로 STA 또는 MTA 스레드에서 특정 COM 인터페이스를 사용할 수있는 경우에 대한 대답을 얻는 유일한 신뢰할 수있는 일반 메서드입니다.

는 COM 개체를 인스턴스화의보다 구체적인 경우에, 당신은 인스턴스화 아파트 유형과 일치 여부를 확인하기 위해 레지스트리 정보를 찾아 볼 수 있습니다. out-of-process 서버는 모든 이벤트에서 마샬링을 통해 COM 인터페이스 포인터를 제공하므로 모든 클라이언트 측 아파트에서이 서버를 사용할 수 있습니다.

서버 오브젝트는 스레드로부터 안전 여부에 의심의 여지가 없다. COM 등록이 정확하면 (특히 STA in-proc 서버가 Free/Both 등록을 알리지 않고 마샬링을 사용할 수있는 경우) 스레드 안전이 무료로 포함됩니다.

+0

고마워요! 나는 COM 관련 자료에 깊이 관여하지 않기 때문에 모든 점을 이해하지 못한다. COM 객체를 전혀 사용하지 않지만 일부 코드는 COM을 사용하는 것 같습니다. 예를 들어, vb.net이 STA를 기본값으로 사용하고 메시지 루프가 thread.Sleep에 의해 차단 되었기 때문에 차단 된 Finalizer가 있습니다. 내가 안전하게 MTA (기본값은 C#)로 바꿀 수 있으며 이후에는 더 이상 신경 쓰지 않아야 함을 확신합니다.). 그러나 많은 조사가 끝난 후에도 이것이 어떻게 든 내 코드를 손상시킬 수 있는지 확실하지 않습니다. – DanielG

+1

COM의 규칙은 아파트간에 직접 포인터를 전달하지 않는다는 것입니다 (일반적으로 STA 스레드에서는 포인터를이 스레드 외부로 가져올 수 없으며 MTA 스레드간에 포인터를 전달할 수 있지만 외부에서는 STA 스레드로 전달할 수 없음). VB.NET 코드에서 COM 인터페이스를 처리 할 때이를 명심해야합니다. .NET 런타임은 추가 검사를 수행하고 포인터의 오용을 방지하므로 모든 단계를 제외하면 예외가 발생할 수 있습니다. –

0

등록 된 COM 개체는 ThreadingModel 필드에 따라 아파트에 속하게됩니다 (COM 아파트에 대해서는 더 크고 더 간단한 테이블이있는 것이 another article입니다).

기본적으로 ThreadingModel입니다 어느 아파트에 새로 생성 된 객체가 속할 알려줍니다 :

를 지정되지
  • 홈페이지 STA (첫 번째 CoInitialize D의 STA, 존재하지 않는 경우는, COM 하나를 생성, 그렇지 않으면, 호스트 STA)

  • 아파트

    STA를 (우리가 STA에 있다면, 그것을있을거야라고 호스트 STA)

  • 무료

    MTA에 (우리가 MTA에 있다면, 그것을 수 있습니다; 그렇지 않으면, COM 그것을 만들고, 호스트 MTA)

  • 중립 현재 아파트를 무엇이든간에 모두

    라고

    중립 아파트

당신이있을 경우 MTA 객체를 사용하고 "thread-safe"한지 의심 스럽습니다 (이는 일반적으로 각 메소드/소품에 인스턴스 수준 잠금을 사용함을 의미합니다). erty 호출), 당신은 정말로 그것에 대해 많은 것을 할 수 없다. 예를 들어 여러 STA가 동일한 MTA 개체에 동시에 액세스 할 수 있습니다.

만들기는 다른 STA를하고 다른 같은 객체를 사용하고 아무도이없는 보장하지 않는 한 STA는 반드시 당신에게이 스레드 안전을 제공하지 않습니다에서 를 호출합니다.

"보증"은 다른 방법으로 작동합니다. 모든 전화는 에서으로 이루어지며 STA는 순차적입니다. 그럼에도 불구하고, STA가 아파트 간 전화를하는 동안 재진입 통화가 허용되므로 이는 실제로는 자물쇠 같은 보증이 아닙니다.

아파트 수준이기 때문에 호출 직렬화는 매우 거친 것이므로 개체에 관계없이 동일한 STA에 대한 모든 호출이 한 번에 하나씩 실행됩니다 (하지만 재진입 프로그램에서 하나씩 실행될 수도 있음). 방법).


편집 : 재진입 전화는 IMessageFilter 제어 할 수 있습니다.