Mesaj pompası nedir?


104

Gelen bu konuya (yaklaşık bir yıl önce yayınlanan) bir interaktif olmayan oturumda Word çalıştıran gelebilir sorunların bir tartışma vardır. Orada verilen (oldukça güçlü) tavsiye, böyle yapmamaktır. Bir gönderide "Office API'lerinin tümü, Office'i bir monitör, klavye ve fare ve en önemlisi bir mesaj pompası ile bir masaüstünde etkileşimli bir oturumda çalıştırdığınızı varsayar." Bunun ne olduğundan emin değilim. (Sadece yaklaşık bir yıldır C # ile programlama yapıyorum; diğer programlama deneyimim öncelikle ColdFusion ile oldu.)

Güncelleme:

Programım, bir tıbbi rapor numarası oluşturmak için kullanılan iki bilgi parçasını çıkarmak için çok sayıda RTF dosyası üzerinden çalışır. RTF'deki biçimlendirme talimatlarının nasıl çalıştığını anlamaya çalışmak yerine, onları Word'de açmaya ve metni oradan çıkarmaya karar verdim (aslında GUI'yi başlatmadan). Zaman zaman, program bir dosyayı işlemenin ortasında hıçkırır ve o belgeye ekli bir Word dizisini açık bırakır (hala bu dosyayı nasıl kapatacağımı bulmam gerekiyor). Programı yeniden çalıştırdığımda, elbette bu dosyayı kullanan bir iş parçacığı olduğuna dair bir bildirim aldım ve salt okunur bir kopya açmak istiyor muydum? Evet dediğimde, Word GUI birdenbire birden ortaya çıktı ve dosyaları işlemeye başladı. Bunun neden olduğunu merak ediyordum;


3
Bu neden win32 olarak etiketlendi? - Mesaj sistemi Windows V1'deydi (Hatırladığım kadarıyla 8 bitti.)
Hogan

Yanıtlar:


187

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.


Çok güzel ve detaylı cevap. Eklemek gerekirse, oluşturulan ilk STA olan ana STA adı verilen özel bir STA da vardır. Hangisi ideal olarak UI iş parçacığınız tarafından oluşturulmalıdır. Ana STA, iş parçacığı modeline sahip bileşenlerin = hiçbirinin oluşturulmadığı yerdir. Ana STA'nız UI iş parçacığınız tarafından oluşturulmamışsa - iş parçacığı modeline sahip olmayan eski activex kontrollerini kullanırken ilginç sorunlarla karşılaşabilirsiniz.
quixver

12

"Mesaj pompası", uygulamanın çeşitli bölümlerine pencereleme mesajlarını göndermekten sorumlu herhangi bir Windows programının temel bir parçasıdır. Bu, Win32 UI programlamanın özüdür. Her yerde bulunmasından dolayı birçok uygulama, mesajları farklı modüller arasında iletmek için mesaj pompasını kullanır; bu nedenle, Office uygulamaları herhangi bir UI olmadan çalıştırılırsa bozulacaktır.

Wikipedia'nın temel bir açıklaması var .


Mesaj döngüsü olmadan bir Windows uygulaması yazmanın imkansız olduğuna inanıyorum, bu nedenle tüm uygulamalar mesaj pompasını kullanıyor.
Hogan 08

2
Ayrıca, basit GUI uygulamaları olmadan da yazabilirsiniz - örneğin, kendi uygulamanızın uygulamanızda bir mesaj döngüsü olmadan mesaj kutularını açabilirsiniz.

DialogBox veya DialogBox aracılığıyla dolaylı olarak bir diyalog oluşturursanız - bir mesaj döngüsüne ihtiyacınız yoktur, sadece pencereler tarafından çağrılacak bir fonksiyon (dlgproc) sağlamanız gerekir. (ve bir mesaj kutusu sadece basit bir iletişim
kutusudur

6

John, Windows sisteminin (ve diğer pencere tabanlı sistemlerin - X Window , orijinal Mac OS ....) bir mesaj sistemi aracılığıyla olayları kullanarak asenkron kullanıcı arayüzlerini nasıl uyguladığından .

Her uygulamanın perde arkasında, her pencerenin olayları diğer pencerelere veya olay dinleyicilere gönderebildiği bir mesajlaşma sistemi vardır - bu, mesaj kuyruğuna bir mesaj eklenerek gerçekleştirilir. Her zaman bu mesaj kuyruğuna bakarak çalışan ve ardından mesajları (veya olayları) dinleyicilere gönderen bir ana döngü vardır.

Microsoft Windows'daki Wikipedia makalesi Mesaj döngüsü, temel bir Windows programının örnek kodunu gösterir - ve görebileceğiniz gibi, en temel düzeyde bir Windows programı yalnızca "mesaj pompası" dır.

Yani, hepsini bir araya getirmek için. Bir UI'yi desteklemek için tasarlanmış bir Windows programının bir hizmet olarak davranamamasının nedeni, UI desteğini etkinleştirmek için her zaman çalışan mesaj döngüsüne ihtiyaç duymasıdır. Bunu açıklandığı gibi bir hizmet olarak uygularsanız, dahili eşzamansız olay işlemeyi işleyemez.


6

Gelen COM , bir mesaj pompa serialises ve de-serialises mesajları daireler arasında göndermiş. Daire, COM bileşenlerinin çalıştırılabildiği mini bir işlemdir. Daireler tek iş parçacıklı ve serbest iş parçacıklı modlarda gelir. Tek iş parçacıklı apartmanlar, esas olarak, çoklu iş parçacığını desteklemeyen COM bileşenlerinin uygulamaları için eski bir sistemdir. Tipik olarak Visual BASIC (çok iş parçacıklı kodu desteklemediğinden) ve eski uygulamalarla birlikte kullanıldılar.

Sanırım Word için ileti pompası gereksinimi , COM API'sinden veya uygulamanın iş parçacığı güvenli olmayan bölümlerinden kaynaklanıyor. Akılda Ayı NET parçacığı ve çöp toplama modelleri kutusunun COM ile güzel dışarı oynamazlar. COM çok basit bir çöp toplama mekanizmasına ve işleri COM yöntemiyle yapmanızı gerektiren iş parçacığı modeline sahiptir. Standart Office PIA'larını kullanmak, yine de COM nesne referanslarını açıkça kapatmanızı gerektirir, bu nedenle oluşturulan her COM tutamacını izlemeniz gerekir. Dikkatli değilseniz, PIA'lar da perde arkasında şeyler yaratacaktır.

.NET-COM entegrasyonu başlı başına bir konudur ve hatta konu üzerine yazılmış kitaplar bile vardır. Etkileşimli bir masaüstü uygulamasından Office için COM API'lerini kullanmak bile, çemberleri atlamanızı ve referansların açıkça yayınlandığından emin olmanızı gerektirir.

Office'in iş parçacığı açısından güvenli olmadığı varsayılabilir, bu nedenle her iş parçacığı için ayrı bir Word, Excel veya diğer Office uygulamalarına ihtiyacınız olacaktır . Başlangıç ​​ek yüküne maruz kalmanız veya bir iş parçacığı havuzunu korumanız gerekir. Tüm COM referanslarının doğru şekilde yayımlandığından emin olmak için bir iş parçacığı havuzunun titizlikle test edilmesi gerekir. Örnekleri başlatmak ve kapatmak bile, tüm referansların doğru şekilde yayımlandığından emin olmanızı gerektirir. I'lerinizi noktalamamak ve burada t'lerinizi geçmemek, çok sayıda ölü COM nesnesine ve hatta Word'ün tüm çalışan örneklerinin sızdırılmasına neden olacaktır.


1
Cevabınızda birkaç yanlışlık var. 3 tip aparat vardır - STA (Tek dişli), MTA (Çok Dişli) ve NTA (Nötr Dişli). Serbest iş parçacığı, serbest iş parçacıklı sıralayıcıyı bir araya getiren bir bileşeni tanımlamak için kullanılır, serbest dişli bir daire diye bir şey yoktur. COM, STA'larla iletişim kurmak için mesajlar kullanır. Bir MTA'da yaşayan (veya serbest iş parçacıklı sıralayıcıyı bir araya getiren) bileşenler için mesaj döngüleri gerekmez. AFAIK - lpc, verileri RPC iş parçacığı havuzundan bir iş parçacığına çağıran verileri sıralamak için kullanılır ve bu daha sonra yöntemi gerçekten çağırır.
quixver


0

Bu Kanal 9 tartışmasının güzel ve özlü bir açıklaması olduğunu düşünüyorum :

Bu pencere iletişim süreci, Windows Mesaj Pompası adı verilen yöntemle mümkün kılınmıştır. Message Pump'ı uygulama pencereleri ile masaüstü arasında işbirliğine olanak sağlayan bir varlık olarak düşünün.


2
vay ... bu korkunç ve yanıltıcı bir alıntı. (Bir "varlık" mı? Err .. no.)
Hogan

4
varlık - nesne: tek bir ayrı nesne olarak var olan veya tek bir ayrı nesne olarak algılanan şey encarta.msn.com/dictionary_1861608661/entity.html
Matthew Whited
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.