Mesaj döngüsü, herhangi bir yerel Windows programında bulunan küçük bir kod parçasıdır. Kabaca şöyle görünür:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GetMessage () Win32 API, Windows'tan bir mesaj alır. Programınız genellikle zamanının% 99,9'unu orada geçirerek Windows'un ilginç bir şey olduğunu söylemesini bekler. TranslateMessage (), klavye mesajlarını çeviren yardımcı bir işlevdir. DispatchMessage (), pencere prosedürünün mesajla çağrılmasını sağlar.
Her GUI etkin .NET programının bir mesaj döngüsü vardır, Application.Run () tarafından başlatılır.
Bir ileti döngüsünün Office ile alaka düzeyi COM ile ilgilidir. Office programları COM özellikli programlardır, Microsoft.Office.Interop sınıfları böyle çalışır. COM, bir COM ortak sınıfı adına iş parçacığı oluşturmaya özen gösterir, bir COM arabiriminde yapılan çağrıların her zaman doğru iş parçacığından yapılmasını sağlar. Çoğu COM sınıfının kayıt defterinde ThreadingModel'lerini bildiren bir kayıt defteri anahtarı vardır, en yaygın olanlar (Office dahil) "Daire" kullanır. Bu, bir arabirim yöntemini çağırmanın tek güvenli yolunun, çağrıyı sınıf nesnesini oluşturan aynı iş parçacığından yapmak olduğu anlamına gelir. Veya başka bir deyişle, çoğu COM sınıfı iş parçacığı açısından güvenli değildir.
Her COM etkin iş parçacığı bir COM dairesine aittir. İki tür vardır, Tek Dişli Daireler (STA) ve Çok İplikli Daire (MTA). Bir STA iş parçacığında grup iş parçacıklı bir COM sınıfı oluşturulmalıdır. Bunu .NET programlarında görebilirsiniz, Windows Forms veya WPF programının UI iş parçacığının giriş noktası [STAThread] özniteliğine sahiptir. Diğer iş parçacıkları için apartman modeli, Thread.SetApartmentState () yöntemi tarafından belirlenir.
UI iş parçacığı STA değilse, Windows tesisatının büyük bölümleri düzgün çalışmayacaktır. Özellikle Sürükle + Bırak, pano, OpenFileDialog gibi Windows diyalogları, WebBrowser gibi kontroller, ekran okuyucular gibi UI Otomasyon uygulamaları. Ve Office gibi birçok COM sunucusu.
Bir STA iş parçacığı için zor bir gereksinim, hiçbir zaman engellememesi ve bir mesaj döngüsünü pompalaması gerektiğidir. İleti döngüsü önemlidir çünkü COM, bir iş parçacığından diğerine bir arabirim yöntemi çağrısını sıralamak için kullanır. .NET çağrıları sıralamayı kolaylaştırsa da (örneğin Control.BeginInvoke veya Dispatcher.BeginInvoke), aslında yapılması çok zor bir iştir. Çağrıyı yürüten iş parçacığı iyi bilinen bir durumda olmalıdır. Bir iş parçacığını keyfi olarak kesip onu bir yöntem çağrısı yapmaya zorlayamazsınız, bu korkunç yeniden giriş sorunlarına neden olur. Bir iş parçacığı "boşta" olmalıdır, programın durumunu değiştiren herhangi bir kodu yürütmekle meşgul olmamalıdır.
Belki bunun nereye gittiğini görebilirsiniz: evet, bir program mesaj döngüsünü yürütürken, boşta. Gerçek sıralama, COM'un oluşturduğu gizli bir pencere aracılığıyla gerçekleşir, bu pencerenin pencere prosedürünün kodu yürütmesi için PostMessage'ı kullanır. STA başlığında. Mesaj döngüsü bu kodun çalışmasını sağlar.