메시지 루프는 모든 기본 Windows 프로그램에 존재하는 작은 코드 조각입니다. 대략 다음과 같습니다.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetMessage () Win32 API는 Windows에서 메시지를 검색합니다. 프로그램은 일반적으로 Windows에서 흥미로운 일이 발생했음을 알리는 데 99.9 %의 시간을 보냅니다. TranslateMessage ()는 키보드 메시지를 번역하는 도우미 함수입니다. DispatchMessage ()는 창 프로 시저가 메시지와 함께 호출되도록합니다.
모든 GUI 사용 .NET 프로그램에는 메시지 루프가 있으며 Application.Run ()에 의해 시작됩니다.
Office에 대한 메시지 루프의 관련성은 COM과 관련이 있습니다. Office 프로그램은 COM 사용 가능 프로그램이므로 Microsoft.Office.Interop 클래스가 작동합니다. COM은 COM coclass를 대신하여 스레딩을 처리하며 COM 인터페이스에 대한 호출이 항상 올바른 스레드에서 이루어 지도록합니다. 대부분의 COM 클래스는 ThreadingModel을 선언하는 레지스트리 키를 레지스트리에 가지고 있으며, 가장 일반적인 클래스 (Office 포함)는 "Apartment"를 사용합니다. 즉, 인터페이스 메서드를 호출하는 유일한 안전한 방법은 클래스 개체를 만든 동일한 스레드에서 호출하는 것입니다. 또는 다른 말로하면 대부분의 COM 클래스는 스레드로부터 안전하지 않습니다.
모든 COM 사용 스레드는 COM 아파트에 속합니다. STA (Single Threaded Apartments)와 MTA (Multi Thread Apartment)의 두 가지 종류가 있습니다. 아파트 스레드 COM 클래스는 STA 스레드에서 만들어야합니다. .NET 프로그램에서 다시 볼 수 있습니다. Windows Forms 또는 WPF 프로그램의 UI 스레드 진입 점에는 [STAThread] 특성이 있습니다. 다른 스레드에 대한 아파트 모델은 Thread.SetApartmentState () 메서드에 의해 설정됩니다.
UI 스레드가 STA가 아닌 경우 Windows 배관의 많은 부분이 제대로 작동하지 않습니다. 특히 Drag + Drop, 클립 보드, OpenFileDialog와 같은 Windows 대화 상자, WebBrowser와 같은 컨트롤, 화면 판독기와 같은 UI 자동화 앱이 있습니다. 그리고 Office와 같은 많은 COM 서버.
STA 스레드에 대한 엄격한 요구 사항은 차단하지 않아야하고 메시지 루프를 펌핑해야한다는 것입니다. 메시지 루프는 COM이 한 스레드에서 다른 스레드로 인터페이스 메서드 호출을 마샬링하는 데 사용하기 때문에 중요합니다. .NET을 사용하면 마샬링 호출이 쉬워 지지만 (예 : Control.BeginInvoke 또는 Dispatcher.BeginInvoke) 실제로 수행하기 매우 까다로운 작업입니다. 호출을 실행하는 스레드는 잘 알려진 상태 여야합니다. 스레드를 임의로 인터럽트하고 메서드 호출을 강제 할 수는 없습니다. 이는 끔찍한 재진입 문제를 유발할 수 있습니다. 스레드는 프로그램 상태를 변경하는 코드를 실행 하느라 바쁘지 않고 "유휴"상태 여야합니다.
아마도 그것이 어디로 이끄는지를 볼 수있을 것입니다. 예, 프로그램이 메시지 루프를 실행할 때 그것은 유휴 상태입니다. 실제 마샬링은 COM이 만든 숨겨진 창을 통해 발생하며 PostMessage를 사용하여 해당 창의 창 프로 시저가 코드를 실행하도록합니다. STA 스레드에서. 메시지 루프는이 코드가 실행되도록합니다.