2010-04-26 3 views
4

타사 COM 라이브러리를 통해 외부 장치와 통신하는 응용 프로그램을 작성하고 있습니다. 나는 장치에 대한 모든 통신을 배경 스레드를 통해 통신을 통해 문제를 방지하고 UI 스레드에서 통신을함으로써 도입 된 몇 가지 다른 복잡성을 없애기 위해 노력하고 있습니다.UI 스레드가 COM 개체를 호출하는 백그라운드 스레드를 차단하고 있습니다.

문제는 메인 UI 스레드가 차단 (즉, MessageBox.Show가 호출되거나 화면 주위로 창을 이동하는 경우) 될 때마다 백그라운드 스레드에서 장치와의 통신도 중지된다는 것입니다.

서로 간섭하지 않도록 두 스레드를 충분히 멀리 떨어 뜨리는 방법 (완전히 별도의 프로세스가 아님)이 있습니까? (일부 수학 계산을 할 때 정확히 같은 코드를 사용하면 작업 속도가 느려집니다. 문제가있는 COM 라이브러리를 사용할 때만 가능합니다.)

+3

매우 이상하게 보입니다. 코드를 보지 않으면 UI 스레드를 사용 중으로 만드는 것이 왜 다른 스레드를 느리게하는지 확실히 알기가 어렵습니다. UI 스레드가 뭔가를하기를 기다리고있는 작업자 스레드에는 어떤 것이 있습니까? –

+1

배경 스레드가 UI에 'Invoke'를 사용하여 메시지 상자를 팝업하도록 알려주고 있습니까? – Paolo

+0

@Paolo, 메시지 상자 나 그와 비슷한 것을 띄우는 것보다 훨씬 자주 발생하는 것처럼 들립니다. 아마 그는 창을 쥐고 그 주위를 움직이는 많은 메시지 상자가 나타나기 때문에 속도가 느려질 것입니다. :) –

답변

11

뒤에 오는 2 개의 조건은 진실하다.

  • 제 3 자 COM 라이브러리는 단일 스레드 아파트
  • 당신은 UI 스레드 실행되기 때문에 UI 스레드

에 라이브러리에서 클래스의 인스턴스를 생성하는 실행하도록 설계 STA (단일 스레드 아파트)에서 COM 클래스가 해당 스레드에서 작성된 경우 UI 스레드가 아닌 스레드에서 시작된 클래스에 대한 모든 호출이 UI 스레드 자체에 정렬됩니다. UI 스레드가 차단되면 COM 클래스에 대한 모든 호출도 차단됩니다.

+1

그 트릭을 했어. COM 개체는 작업자 스레드로 전달되기 전에 UI 스레드에서 만들어졌습니다. 작업자 스레드 자체로 이동하면 문제가 사라졌습니다. – AlphaKilo

2

브라이언의 답을 작성하고 싶습니다.

작업자 스레드에 TrySetApartmentState(ApartmentState.STA) (으)로 전화하는 것을 잊어 버릴 수 있습니까? 그렇다면 작업자 스레드가 기본적으로 MTA에서 실행되고 모든 STA 개체가 별도의 STA 스레드 (기본 UI 스레드 일 수도 있음)에서 생성된다고 생각합니다. 작업자 스레드가 STA에 가입하고 이것이 도움이되는지 확인해야합니다.

이외에도 COM 개체를 주 STA로 등록 할 수 있습니다. IIRC, 이것은 흔하지 않습니다. Main-STA 개체 은 기본 UI 스레드에으로 살아야합니다. 이런 경우가 발생한다면, 유일한 대안은 작업자 스레드 대신 작업자 프로세스에 의존하는 것입니다.

관련 문제