2011-10-28 2 views
4

COM을 처음으로 사용합니다. 이 COM dll이 있는데, ABCServer.dll이라고 말하면서 RCW를 만들고이 프로젝트에 대한 참조를 추가했습니다. 이제는 내 응용 프로그램이 여러 스레드를 만들고 각 스레드는 COM DLL에서 특정 클래스를 만들고 그 스레드에서 작동합니다. 하지만 다른 스레드가 COM DLL에서 특정 클래스로 작업하는 동안 각 스레드가 기다리고 있습니다.COM 멀티 스레딩 지원

내 애플리케이션을 수정하는 목적이 멀티 스레딩을 가능하게하고있었습니다. 이제 내 측면에서 멀티 스레딩이 발생하면 COM은이를 연속적으로 발생시킵니다. 각 스레드가 새 인스턴스를 작성하고 있지만 다른 사람들이 처리되기를 기다리는 이유는 무엇입니까?

+0

COM 구성 요소가 STA (Single Threaded Apartment) 또는 MTA (Multi Threaded Apartment)로 선언 되었습니까? – Seb

+0

어떻게 확인합니까? – EagerToLearn

+0

@EagerToLearn 참조하십시오 http://stackoverflow.com/questions/2722867/how-to-determine-threading-model-of-given-com-library – shf301

답변

1

지금까지 게시 한 댓글과 답변에는 상당한 혼란이 있습니다. STA 또는 MTA는 스레드의 속성입니다. 그러나 중요한 것은 COM 구성 요소에 필요한 것입니다. ThreadingModel 레지스트리 값에 선언되어 있습니다. 매우 일반적인 환경 인 "Apartment"를 발견했습니다. 구성 요소가 스레딩을 지원하지 않는다는 의미입니다.

.NET Framework의 대부분의 클래스와 달리 스레드 안전성은 거의 없습니다. 큰 차이점은 COM 은 스레딩 안전성이입니다. .NET 클래스를 사용하면 코드를 작성하여 클래스 객체를 스레드로부터 안전하게 사용할 수 있습니다. 어려운 일이 아니며 만성적으로 버그를 진단 할 수있는 만성적 인 소스가 있지만 잘 설계된 잠금을 사용하면 제한 사항을 해결할 수 있습니다. COM에서는 그럴 수 없으며, 항상 도움이되지 않으면 스레드 안전성을 제공합니다. 당신이 도와주고 싶어도.

앞서가는 유일한 방법은 하나의 스레드에서만 COM 구성 요소를 만들고 사용하는 것입니다. 이 스레드는 STA를 선택하기 위해 Thread.SetApartmentState()로 초기화되어야합니다. COM에 대해 구성 요소에 대한 안전한 피난처를 찾기 위해 자체 스레드를 만들지 못하게합니다. 그리고 STA 요구 사항 인 메시지 루프를 펌프해야합니다. 다른 스레드에서 COM 구성 요소를 사용하려고하지 않고 구성 요소 자체가 메시지 펌프를 사용할 수 있는지 여부에 의존하지 않는 경우 고통 스럽거나 일 수 있습니다.은 피해야합니다. 어느 것이 꽤 일반적인 btw입니다. 반응이 없어지면 예상되는 이벤트가 발생하지 않는 것을 알 수 있습니다. 같은 스레드의 COM 개체에 대한 호출 만 수행하여 자체 개체를 만드는 다른 스레드와의 동시성을 확보하십시오. 이것은 일반적으로 유용하거나 가능하지 않습니다.

4

COM 구성 요소가 STA (single-threaded apartment)으로 표시된 경우 멀티 스레딩 할 수있는 방법이 없습니다. 구성 요소의 요구 사항은 모든 호출이 STA가있는 스레드로 직렬화되며 COM이 자동으로 처리합니다.

귀하의 구성 요소가 STA 구성 요소이고 그 것처럼 보이는 경우 multi-threaded apartment component (MTA) 또는 그 이상으로 변경할 수 없으므로 free-threaded (아파트 사이에 마샬링이 전혀 없음) a) VB6로 작성되었거나 b) 써드 파티 dll이라면 어떤 종류의 큐 모델로 작업하는 것이 좋습니다.

기본적으로 모든 다른 작업을 비동기 적으로 실행 한 다음 가능한 한 빨리 한 번에 하나씩이 구성 요소를 호출하라는 요청을 사용하는 스레드 또는 프로세스가 있습니다 (여러 스레드에서이 구성 요소의 여러 인스턴스를 인스턴스화 할 수 있습니다. ApartmentState property on the Thread classApartmentState.STA으로 설정 한 다음 호출이 완료되면 이벤트/콜백을 게시하고 다른 작업을 비동기식으로 계속 진행하면됩니다.

기본적으로 두 개의 생산자/소비자 구현, 즉 COM 구성 요소에 대한 호출을 보내고, 다른 하나는 완료 될 때 결과를 전달하는 것과 같습니다.

1

각 스레드가 Apartment-model 개체의 자체 인스턴스를 만들고 각 스레드가 STA에서 실행되도록 표시된 경우 각 스레드는 별도의 STA에 있어야하며 COM 개체 인스턴스가 실행되어야합니다 별도의 STA.

다른 답변은 COM 인스턴스가 모두 같은 아파트에 있다고 가정합니다. COM 개체 인스턴스를 만들기 전에 각 스레드가 STA에 있는지 확인하기 위해 Thread.SetApartmentState()를 호출하면 해당 스레드의 COM 개체는 다른 스레드의 STA와 별개로 해당 스레드의 STA에 있어야합니다. 그러면 다른 STA에있는 객체에 대한 호출의 직렬화를 볼 수 없습니다.

+0

최신 결과를 알려 드리겠습니다. COM DLL은 JVM을 사용하여 서버에 연결하고 요청/응답 파일을 제출/수신합니다. 응용 프로그램의 두 인스턴스를 실행하면 원격 서버 로그에 두 개의 세션이 생성 된 것으로 표시되는 반면 응용 프로그램의 단일 인스턴스에서 여러 요청을 사용하면 요청이 대기중인 패션 및 서버 로그 쇼에서 서버에 제출되는 것으로 나타납니다 하나의 세션 만 생성됩니다. 난 백만 가지 이유가있을 수 있지만 전문가는 황소의 눈을 낳을 수 있습니다. – EagerToLearn

+0

좋아, 모든 COM 개체가 동일한 STA에 있었고 호출이 직렬화되었다고해서 왜 한 세션 만 얻었는지 설명 할 수 없습니다. 서버. 프로세스 당 단일 세션을 관리하는 COM 객체 내부에 논리가있는 것처럼 들립니다. – Martin

+0

그렇습니다. 두 개의 응용 프로그램 인스턴스 (각각 자체 COM 참조 DLL이있는)를 실행하면 두 개의 세션이 사용되는 반면 COM 참조 DLL이있는 단일 인스턴스 내에서 여러 요청이있을 때만 하나만 사용됩니다. – EagerToLearn