문제

이에 의해 트리거 다른 질문.

특히,나는 과정에서 COM 클래스에 정의되어 있는 CLSID 레지스트리ThreadingModelBoth.

우리의 프로세스를 활성화를 통해 이 개체 CoCreateInstance ( CoCreateInstanceEx, 는 경우에도 문제에 대한 proc dll server)

부여 실을 꿰는 모델의 Both고 번째 규칙에 나열 문서:

Threading model of server | Apartment server is run in
------------------------------------------------------
Both                      | Same apartment as client

고 주어진 것에 한스 기록에는 다른 응답:

...마샬링을 때 발생하는 클라이언트 통화 요구를 만들 수 있에 다른 스레드가 있습니다....한 경우에 발생할 수 있습 ThreadingModel 에서 지정 comClass 요소를 요구한다.다시 말해서,COM 체 에서 만들어진 하나의 스레드 그러나라에 다른 서버가 지 않는 스레드에 안전합니다.

내 잠정 결론을 것 같은 객체 필요한 암시적 마샬링의 통화는 인터페이스,이후 개체가 항상 살아서 같은 아파트로 그것의 클라이언트입니다.

는 올바른 경우에도 클라이언트 프로세스로 실행 STA?

도움이 되었습니까?

해결책

예, 마샬링이있을 수 있습니다.

COM 클래스의 클라이언트가 STA에서 실행 중이고 다른 아파트에서 수업을 불러 오려고하면 만들어진 아파트로 마샬링해야합니다.

COM 용어는 정말 혼란 스러울 수 있습니다. 이 경우 '클라이언트'를 참조하면 실제로 전체 응용 프로그램이 아닌 스레드를 참조합니다 (암시 함).

Both 단지 서버의 스레딩 모델이 서버를 인스턴스화하는 클라이언트를 준수한다는 것을 의미합니다. 즉, 수업을 인스턴스화하면 생성 된 스레드의 스레딩 모델을 사용합니다. STA에서 서버를 인스턴스화하므로 서버는 STA를 사용하므로 생성 된 스레드에서만 호출 할 수 있습니다. 다른 스레드가 그것을 호출하려고 시도하면, 그것이 생성 된 스레드에 마샬링됩니다.

다른 팁

질문에 대한 직접적인 해답은 아니지만 나 자신이 게시하는 것을 도울 수 없습니다.

Com의 황금 시대의 훌륭한 MSKB 기사가 있습니다. 정보 : 올레 스레딩 모델의 설명 및 작업. 여전히 거기에 있으며 모든 관련 정보가 있습니다. 요점은 규칙을 따르는 경우 마샬링이 있는지 여부에 대해 걱정해서는 안됩니다.. 객체를 그냥 등록하십시오 ThreadingModel=Both, 프리 스레드 마샬을 집계하십시오 CoCreateFreeThreadedMarshaler, 그리고 끝납니다. Com은 필요한 경우 가능한 한 최선의 방법으로 마샬링을 할 것입니다. 클라이언트의 아파트 모델에 따라 클라이언트 코드는 규칙을 따르는 경우 인터페이스에 대한 직접 포인터를받을 수 있습니다.

인터페이스의 메소드가 호출 될 때받을 수있는 "Alien"인터페이스는 동일한 스레드에 머무르기 때문에 통화 범위에서 유효합니다. 저장할 필요가 없다면 그게 전부입니다.

그러나 "Alien"인터페이스를 캐시 해야하는 경우이 작업을 수행하는 올바른 방법은 사용하는 것입니다. CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream:

그것을 보관하려면 :

  • 임계 섹션을 입력하십시오.
  • 전화 CoMarshalInterThreadInterfaceInStream 그리고 저장 IStream 멤버 필드의 포인터;
  • 중요한 섹션을 남겨 두십시오.

그것을 검색하려면

  • 임계 섹션을 입력하십시오.
  • 전화 CoGetInterfaceAndReleaseStream 인터페이스를 검색합니다
  • 전화 CoMarshalInterThreadInterfaceInStream 그리고 다시 보관하십시오 IStream 향후 사용하기 위해
  • 중요한 섹션을 남겨 두십시오.
  • 현재 통화 범위에서 인터페이스를 사용하십시오.

그것을 발표하려면 :

  • 더 이상 보관할 필요가 없으면 저장된 저장을 해제하십시오. IStream (중요 섹션 내부).

"외계인"객체도 프리 스레드가 있고 동일한 프로세스 내에서 발생하는 일이 발생하면 직접 인터페이스 포인터를 다루게 될 것입니다. CoGetInterfaceAndReleaseStream. 그러나, 당신은 어떤 가정도하지 않아야하며, 당신이 다루는 객체가 원래 객체인지 com Marshaller 프록시인지 알 필요가 없습니다.

사용하여 약간 최적화 할 수 있습니다 CoMarshalInterface w/ MSHLFLAGS_TABLESTRONG / CoUnmarshalInterface / IStream::Seek(0, 0) / CoReleaseMarshalData 대신에 CoGetInterfaceAndReleaseStream/CoGetInterfaceAndReleaseStream, 스트림을 풀지 않고 필요한만큼 동일한 인터페이스를 마실 수 없습니다.

스레드 로컬 스토리지와 관련하여 더 복잡하고 더 효율적인 캐싱 시나리오가 가능합니다. 그러나 나는 그것이 과잉 일 것이라고 믿는다. 나는 어떤 타이밍도하지 않았지만 오버 헤드라고 생각합니다. CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream정말 낮습니다.

즉, 상태를 유지해야한다면 스레드 친화력이 필요할 수있는 모든 자원이나 개체를 저장합니다., 앞서 언급 한 COM 인터페이스 외에, 당신 해서는 안됩니다 당신의 객체를 다음과 같이 표시하십시오 ThreadingModel=Both 또는 FTM을 집계하십시오.

예,마샬링은 여전히 가능하다.의 몇 가지 예:

  1. 객체를 인스턴스화에서 MTA 스레드와 그 위치로 MTA 아파트와 그것의 포인터로 전달 모든 STA 실과는 STA 스레드를 호출 방법의 개체입니다.이 경우에는 STA 스레드에만 액세스할 수 있습 객체를 통해 정렬.

  2. 객체를 인스턴스화에서 STA 스레드와 그 위치로 STA 에 속하는 아파트에는 스레드한 다음 해당 포인터로 전달되는 또 다른 스타는 스레드 또는 MTA thread.두 경우 모두에서 해당 스레드에만 액세스할 수 있습 객체를 통해 정렬.

사실 기대할 수 있습니다 no 마샬링에서만 다음과 같은 두 가지 경우:

  1. 객체를 인스턴스화에서 MTA 스레드한 다음에만 액세스하여 MTA 스레드를 모두 하나 인스턴스화체 및 모든 기타 MTA 의 스레드 응용 프로그램입니다.
  2. 객체를 인스턴스화에서 STA 스레드가 다음에만 액세스는 매우 실

과 다른 모든 경우에서 정렬하는 것입니다.

ThreadingModel=이 모두 단순히는 것을 의미 COM 서버에 저자할 수 있게 보증하는 자신의 코드에 스레드를 안전 하지만 줄 수 없습니다 같은 것을 보장 기타 코드 그를 작성하지 않은 것이라고 스레드에 안전한 방법입니다.가장 일반적인 받은 경우 등 외국의 코드를 실행은 콜백을 통해,연결 포인트는 가장 일반적인 예를 들어(일반적으로"이벤트"라는 클라이언트에서 런타임).

그렇다면 서버 인스턴스를 만들었 STA 클라이언트 프로그래머가 기대하는 이벤트에서 실행하는 것 같은 스레드가 있습니다.는 경우에도 서버는 방법을 발생한 이벤트가 다른 스레드에서 호출.을 필요로 하는 전화 마샬링될.

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