STAThread 및 멀티 스레딩


102

STAThread의 MSDN 기사에서 :

응용 프로그램의 COM 스레딩 모델이 STA (단일 스레드 아파트)임을 나타냅니다.

(참고로 전체 기사 입니다.)

싱글 스레드 아파트 ... 좋아, 그건 내 머리 위로 갔다. 또한 응용 프로그램이 COM interop을 사용하지 않는 한이 속성은 실제로 아무 작업도 수행하지 않는다는 것을 읽었습니다. 그렇다면 정확히 무엇을하고 멀티 스레드 애플리케이션에 어떤 영향을 미칠까요? 다중 스레드 응용 프로그램 ( Timers를 사용하는 모든 사람부터 스레드 풀 등의 비동기 메서드 호출에 이르기까지 포함 )은 MTAThread를 사용해야하나요? STAThread와 MTAThread는 실제로 무엇을합니까?

답변:


60

아파트 스레딩은 COM 개념입니다. COM을 사용하지 않고 호출하는 API가 "내부에서"COM을 사용하지 않는다면 아파트에 대해 걱정할 필요가 없습니다.

아파트에 대해 알아야 할 경우 세부 사항 이 약간 복잡해질 수 있습니다 . 아마도 지나치게 단순화 된 버전은 STA로 태그가 지정된 COM 개체는 STAThread에서 실행되어야하고 MTA로 표시된 COM 개체는 MTA 스레드에서 실행되어야한다는 것입니다. 이러한 규칙을 사용하여 COM은 이러한 서로 다른 개체 간의 호출을 최적화하여 필요하지 않은 마샬링을 방지 할 수 있습니다.


7
그것은 지나치게 단순화되었습니다. 다중 스레드 개체는 모든 스레드에서 실행할 수 있습니다. 아파트 스레드 개체는 생성 된 아파트에서만 실행할 수 있습니다.
1800 INFORMATION

28
STA 스레드의 STA 개체에서 MTA 개체로의 호출은 MTA 스레드로 마샬링됩니다 (MTA 개체가 자유 스레드 마샬 러를 구현하지 않는 경우). 내가 말했듯이 세부 사항은 복잡해질 수 있습니다. (I는 수년 동안 COM 팀에 근무 미소 )
브루스

9
COM을 직접 사용하지 않는 경우에도이 사실을 알고 있어야합니다. 스레드는 그래픽 창을 표시하는 경우 단일 스레드 아파트 모델을 사용해야합니다. 이것이 바로 Windows Forms 응용 프로그램에서 [STAThread]가 항상 기본 메소드 위에 표시되는 이유입니다.
Justin Ethier

6
글꼴 또는 파일 대화 상자와 같은 것이 사용자 모르게 COM을 사용할 수 없습니까? 내부적으로 수행한다고 가정합니다. 거의 모든 Windows Forms 응용 프로그램에서 STAThread를 설정해야한다는 의미가 아닙니까? 실제로 COM 프로그래밍을하지 않았으므로 내 가정을 용서하십시오.
Brett Ryan

4
관심있는 것들에 대한 더 자세한 대답은 : stackoverflow.com/questions/4154429/apartmentstate-for-dummies
jgauffin

3

그것이 무엇을 하는가는 CoInitializeCOINIT_APARTMENTTHREADED를 매개 변수로 지정하여 호출되도록합니다. COM 구성 요소 또는 ActiveX 컨트롤을 사용하지 않으면 전혀 영향을 미치지 않습니다. 그렇게한다면 그것은 매우 중요합니다.

아파트 스레드 인 컨트롤은 사실상 단일 스레드이며 해당 컨트롤에 대한 호출은 해당 컨트롤이 생성 된 아파트에서만 처리 될 수 있습니다.

MSDN의 자세한 내용 :

STA (단일 스레드 아파트)에서 생성 된 개체는 해당 아파트의 스레드에서만 메서드 호출을 수신하므로 호출이 직렬화되고 메시지 큐 경계에만 도착합니다 (Win32 함수 PeekMessage 또는 SendMessage가 호출 될 때).

MTA (다중 스레드 아파트)의 COM 스레드에서 만든 개체는 언제든지 다른 스레드에서 메서드 호출을받을 수 있어야합니다. 일반적으로 개체의 데이터를 보호하는 데 도움이되는 중요 섹션, 세마포 또는 뮤텍스와 같은 Win32 동기화 기본 요소를 사용하여 다중 스레드 개체의 코드에서 일종의 동시성 제어를 구현합니다.

NTA (중립 스레드 아파트)에서 실행되도록 구성된 개체가 STA 또는 MTA에있는 스레드에 의해 호출되면 해당 스레드는 NTA로 전송됩니다. 이 스레드가 나중에 CoInitializeEx를 호출하면 호출이 실패하고 RPC_E_CHANGED_MODE를 반환합니다.


MSDN 기사는 COM 관점에서 유용하지만 / ? 속성 CoInitialize()에 대한 응답으로 .NET이 호출 될 때 알려줄 수 있습니까? 참고 : MSDN의 문서는 여기에 있습니다 : CoInitializeEx function . STAThreadApartmentState
jrh

않는 스레드 -> SetApartment는 사용 CoInitialize()내부적으로? 나는 STAThread 속성을 아래까지 추적했지만 흔적이 차가워졌습니다 (에 대한 소스를 찾을 수 없습니다 Thread::SetApartment). thread.h (COM thread.h)의 Thread 클래스가 어디에나 문서화되어 있습니까? MFC, ATL 또는 다른 것입니까?
jrh

@jrh 미안한 것보다 더 자세한 내용은 모릅니다
1800 INFORMATION

-15

STAThread는 C # GUI 프로젝트의 Main 함수 앞에 작성됩니다. 프로그램이 단일 스레드를 생성하도록 허용하는 것 외에는 아무 일도하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.