2009-04-12 5 views
2

나는 dotnet에서 사용하고있는 COM 객체를 가지고 있으며 항상 같은 스레드에서 호출해야합니다. 문제는 개념적으로 프로그램 전체에 걸쳐 여러 가지 일을한다는 것입니다. 이 특정 배경 스레드에서이 객체의 모든 용도가 호출되도록하는 가장 좋은 방법은 무엇입니까? 예제 코드는 훌륭합니다.하나의 특정 스레드에서 객체 사용

+0

왜 같은 스레드에서 개체를 호출해야하는지 설명하지 않았습니다. 여러 가지 이유가있을 수 있으며, 각각마다 약간 다른 권장 사항이 있습니다. 내 질문 : 개체 자체가 신경 써야합니까? STA입니까? 이것은 귀하의 신청서에 대한 조건입니까? 개체가 어떤 종류의 창/GDI 조작에 관여합니까? "특정 스레드"가 기본 UI 스레드입니까? –

+0

개체가 COM 개체이므로 항상 동일한 스레드에서 호출해야하므로이 작업을 수행해야합니다. – leora

+0

COM 개체에는 COM 개체이기 때문에 모든 스레드가 동일한 스레드에서 호출되어야합니다. 사실, 당신이 원하는 모든 스레드에서 대부분의 COM 개체를 호출하는 방법이 있습니다. 일부 개체에는 이러한 요구 사항이 있으며 때로는 클라이언트 응용 프로그램이 필요합니다. 더 구체적으로 설명해 드리겠습니다. a) STA 개체, MTA 또는 자유 스레드인지 여부를 알고 있습니까? b) 객체의 소스 코드를 제어합니까? c) * 귀하의 * 클라이언트 프로그램은 어떤 쓰레드가 사용되는지에 관심을 갖습니까? –

답변

2

프로그램 시작시 모든 COM 상호 작용을 처리해야하는 스레드를 시작할 수 있습니다. 그런 다음 스레드가 처리 할 수있는 대기열에 작업을 푸는 래퍼 객체를 가질 수 있습니다.

래퍼는 호출자에게 다중 스레드를 숨기기 (즉, 래핑 된 호출을 동기 메서드로 노출)하기 위해 동기화 코드를 포함 할 수 있습니다.

WinForms 프로젝트 인 경우 GUI 스레드와 Control.Invoke 메서드를 사용하여 모서리를자를 수 있습니다. (그러나 전화가 오랜 시간이 걸리는 경우에는 통화 중에 UI를 차단할 것이므로 좋은 생각이 아닙니다.)

0

STA에서 개체를 사용할 수 있으면 동일한 스레드에서 호출되도록 부여됩니다.
당신은 메인에 STAThreadAttribute을 추가해야합니다.
유일한 문제는 ALL COM 개체가 그런 식으로 처리된다는 것입니다.

0

이렇게하려면 특정 스레드에 특정 호출을 가져 오는 방법을 먼저 설정해야합니다. 닷넷에는이 작업을 수행하는 몇 가지 기본 메커니즘이 있지만 가장 쉬운 방법은 SynchronizationContext 클래스를 찾는 것입니다. WinForms와 WPF는 모두 메시지 루프를 실행하는 모든 스레드에 대해 SynchronizationContext 인스턴스를 설정합니다.

그래서 것 ...

  • 가 작성하는 스레드
  • 잡고에서 SynchronizationContext를 숨겨진 윈폼 또는 WPF 창을 만들고 실행 개체에 대한 새 스레드를 시작합니다 해당 스레드의 COM 개체

이제 COM 개체의 위치와 다시 전화를받을 수있는 방법이 있습니다. 올바른 스레드. 다음 단계는 프록시 객체를 생성하는 것입니다. 이 개체는 COM 개체에 대한 모든 메서드가 있어야하며 잠재적으로 COM 인터페이스도 구현해야합니다. 그런 다음 모든 메소드 호출을 취하고 동기화 컨텍스트를 사용하여 실제 COM 객체에 대한 호출을 프록시합니다.

public class Foo { 
    private ComFoo _com; 
    private SynchronizationContext _context; 
    public void Bar() { 
    _context.Send(notUsed => _com.Bar();); 
    } 
} 
+0

@ JaredPar, 아주 좋은 대답의 시작이지만, 개인적으로는 빨리 작동하도록 더 많은 것을 필요로 할 것입니다. 아마도 다른 사람들도 마찬가지 였을 것입니다. 숨겨진 창이 무엇인지 보여줄 수 있습니까? assoc하는 방법. 그것과 스레드? –

관련 문제