मैसेज पंप क्या है?


104

में इस सूत्र (लगभग एक वर्ष पहले पोस्ट) समस्याओं है कि एक गैर-सहभागी सत्र में पद चल साथ आ सकते हैं की चर्चा होती है। वहाँ दी गई (काफी मजबूत) सलाह ऐसा नहीं करना है। एक पोस्ट में यह कहा गया है "कार्यालय एपीआई सभी मानते हैं कि आप एक डेस्कटॉप पर एक इंटरैक्टिव सत्र में मॉनिटर, कीबोर्ड और माउस के साथ कार्यालय चला रहे हैं और, सबसे महत्वपूर्ण, एक संदेश पंप।" मुझे यकीन नहीं है कि वह क्या है। (मैं C # में लगभग एक वर्ष से प्रोग्रामिंग कर रहा हूं; मेरा अन्य प्रोग्रामिंग अनुभव मुख्य रूप से ColdFusion के साथ रहा है।)

अपडेट करें:

मेरा कार्यक्रम एक बड़ी संख्या में आरटीएफ फ़ाइलों के माध्यम से चलता है जो कि मेडिकल रिपोर्ट नंबर के निर्माण के लिए उपयोग की जाने वाली जानकारी के दो टुकड़ों को निकालने के लिए है। कोशिश करने और यह पता लगाने के बजाय कि आरटीएफ में प्रारूपण निर्देश कैसे काम करते हैं, मैंने उन्हें केवल वर्ड में खोलने और वहां से पाठ को बाहर खींचने का फैसला किया (वास्तव में जीयूआई शुरू किए बिना)। कभी-कभी, प्रोग्राम एक फ़ाइल को संसाधित करने के बीच में हिचकी लेता है, और उस दस्तावेज़ से जुड़ा एक वर्ड थ्रेड खुला छोड़ दिया जाता है (मुझे अभी भी यह पता लगाना है कि उस एक को कैसे बंद किया जाए)। जब मैंने कार्यक्रम को फिर से चलाया, तो निश्चित रूप से मुझे एक सूचना मिली कि उस फ़ाइल का उपयोग करने वाला एक धागा था, और क्या मैं एक रीड-ओनली कॉपी खोलना चाहता था? जब मैंने कहा, हाँ, GUI शब्द अचानक कहीं से नहीं आया और फ़ाइलों को संसाधित करना शुरू कर दिया। मैं सोच रहा था कि ऐसा क्यों हुआ;


3
इसे win32 के रूप में क्यों टैग किया गया है? - संदेश प्रणाली विंडोज V1 में थी (जो, जैसा कि मुझे याद है 8 बिट था।)
होगन

जवाबों:


187

एक संदेश लूप कोड का एक छोटा सा टुकड़ा होता है जो किसी भी मूल विंडोज प्रोग्राम में मौजूद होता है। यह लगभग इस तरह दिखता है:

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{ 
   TranslateMessage(&msg); 
   DispatchMessage(&msg); 
} 

GetMessage () Win32 एपीआई विंडोज से एक संदेश को पुनः प्राप्त करता है। आपका कार्यक्रम आम तौर पर अपना 99.9% समय वहां बिताता है, विंडोज के लिए यह बताने के लिए इंतजार कर रहा है कि यह कुछ दिलचस्प हुआ। TranslMessage () एक हेल्पर फ़ंक्शन है जो कीबोर्ड संदेशों का अनुवाद करता है। DispatchMessage () सुनिश्चित करता है कि विंडो प्रक्रिया को संदेश के साथ कहा जाता है।

प्रत्येक GUI सक्षम .NET प्रोग्राम में एक संदेश लूप है, यह Application.Run () द्वारा शुरू किया गया है।

Office के लिए एक संदेश लूप की प्रासंगिकता COM से संबंधित है। ऑफिस प्रोग्राम COM- इनेबल्ड प्रोग्राम्स हैं, जो Microsoft.Office.Interop क्लासेस काम करते हैं। COM एक कोकलैस की ओर से थ्रेडिंग का ख्याल रखता है, यह सुनिश्चित करता है कि COM इंटरफ़ेस पर किए गए कॉल हमेशा सही थ्रेड से किए जाते हैं। अधिकांश COM वर्गों की रजिस्ट्री में एक रजिस्ट्री कुंजी है जो अपने थ्रेडिंगमॉडल की घोषणा करती है, अब तक सबसे आम लोगों (कार्यालय सहित) "अपार्टमेंट" का उपयोग करते हैं। जिसका मतलब है कि इंटरफ़ेस विधि को कॉल करने का एकमात्र सुरक्षित तरीका उसी ऑब्जेक्ट से कॉल करना है जिसने क्लास ऑब्जेक्ट बनाया है। या इसे दूसरे तरीके से रखने के लिए: अब तक अधिकांश COM कक्षाएं थ्रेड-सुरक्षित नहीं हैं।

हर COM सक्षम धागा एक COM अपार्टमेंट के अंतर्गत आता है। दो प्रकार के हैं, सिंगल थ्रेडेड अपार्टमेंट (एसटीए) और एक मल्टी थ्रेड अपार्टमेंट (एमटीए)। अपार्टमेंट थ्रेडेड COM क्लास को STA थ्रेड पर बनाया जाना चाहिए। आप इसे वापस .NET प्रोग्राम में देख सकते हैं, Windows फॉर्म या WPF प्रोग्राम के UI थ्रेड के प्रवेश बिंदु में [STAThread] विशेषता है। अन्य थ्रेड्स के लिए अपार्टमेंट मॉडल Thread.SetApartmentState () विधि द्वारा सेट किया गया है।

अगर UI थ्रेड STA नहीं है, तो विंडोज प्लंबिंग का बड़ा हिस्सा सही तरीके से काम नहीं करेगा। विशेष रूप से ड्रैग + ड्रॉप, क्लिपबोर्ड, ओपनफाइलडायलॉग जैसे विंडोज संवाद, वेबब्रोसर, स्क्रीन रीडर जैसे यूआई ऑटोमेशन ऐप को नियंत्रित करता है। और कई COM सर्वर, जैसे कार्यालय।

STA थ्रेड के लिए एक सख्त आवश्यकता यह है कि यह कभी भी ब्लॉक नहीं होना चाहिए और एक संदेश लूप को पंप करना चाहिए। संदेश लूप महत्वपूर्ण है, क्योंकि COM एक इंटरफ़ेस विधि को एक थ्रेड से दूसरे में कॉल करने के लिए COM का उपयोग करता है। हालाँकि .NET मैशलिंग कॉल को आसान बनाता है (Control.BeginInvoke या Dispatcher.BeginInvoke उदाहरण के लिए), यह वास्तव में बहुत मुश्किल काम है। थ्रेड जो कॉल निष्पादित करता है वह एक प्रसिद्ध स्थिति में होना चाहिए। आप केवल मनमाने ढंग से एक थ्रेड को बाधित नहीं कर सकते हैं और इसे एक विधि कॉल करने के लिए मजबूर कर सकते हैं, जिससे भयानक फिर से प्रवेश की समस्या पैदा होगी। एक धागा "निष्क्रिय" होना चाहिए, न कि किसी भी कोड को निष्पादित करने में व्यस्त होना चाहिए जो कार्यक्रम की स्थिति को बदल रहा है।

शायद आप देख सकते हैं कि कहां जाता है: हां, जब कोई प्रोग्राम मैसेज लूप निष्पादित कर रहा है, तो यह निष्क्रिय है। वास्तविक मार्शलिंग एक छिपी हुई खिड़की के माध्यम से होता है जिसे COM बनाता है, यह उस विंडो निष्पादन कोड की विंडो प्रक्रिया के लिए PostMessage का उपयोग करता है। STA थ्रेड पर। संदेश लूप सुनिश्चित करता है कि यह कोड चलता है।


बहुत अच्छा और विस्तृत जवाब। बस जोड़ने के लिए - मुख्य एसटीए नामक एक विशेष एसटीए भी है, जिसे पहले एसटीए बनाया गया है। जो आदर्श रूप से आपके UI थ्रेड द्वारा बनाई गई होनी चाहिए। मुख्य एसटीए वह जगह है जहां थ्रेडिंग मॉडल वाले घटक = कोई भी निर्मित नहीं होता है। यदि आपका मुख्य एसटीए आपके यूआई थ्रेड द्वारा निर्मित नहीं है - तो आप पुराने एक्ट्रेक्स नियंत्रणों का उपयोग करते समय दिलचस्प मुद्दों में भाग सकते हैं जिनमें थ्रेडिंग मॉडल कोई भी नहीं है।
क्विक्सर

12

"संदेश पंप" किसी भी विंडोज प्रोग्राम का एक मुख्य हिस्सा है जो कि एप्लिकेशन के विभिन्न हिस्सों में विंडो संदेश भेजने के लिए जिम्मेदार है। यह Win32 UI प्रोग्रामिंग का मूल है। इसकी सर्वव्यापकता के कारण, कई एप्लिकेशन विभिन्न मॉड्यूल के बीच संदेशों को पारित करने के लिए संदेश पंप का उपयोग करते हैं, यही कारण है कि यदि वे किसी भी यूआई के बिना चलाए जाते हैं तो कार्यालय अनुप्रयोग टूट जाएगा।

विकिपीडिया का मूल विवरण है


मेरा मानना ​​है कि एक संदेश लूप के बिना एक विंडोज़ ऐप लिखना असंभव है, इस प्रकार सभी एप्लिकेशन संदेश पंप का उपयोग करते हैं।
होगन

2
आप एक के बिना सरल जीयूआई ऐप भी लिख सकते हैं - उदाहरण के लिए, आप अपने ऐप में बिना मैसेज लूप वाले अपने ऐप में मैसेज बॉक्स पॉप अप कर सकते हैं।

यदि आप DialogBox या DialogBox के माध्यम से अप्रत्यक्ष रूप से एक संवाद बनाते हैं - तो आपको एक संदेश लूप की आवश्यकता नहीं है, आपको बस एक फ़ंक्शन (dlgproc) की आपूर्ति करने की आवश्यकता है जिसे विंडोज़ द्वारा बुलाया जाएगा। (और एक संदेश बॉक्स सिर्फ एक साधारण संवाद है)
क्विक्स्वर

6

जॉन के बारे में बात कर रहे हैं कि कैसे विंडोज सिस्टम (और अन्य विंडो आधारित सिस्टम - एक्स विंडो , मूल मैक ओएस ....) एक संदेश प्रणाली के माध्यम से घटनाओं का उपयोग कर अतुल्यकालिक उपयोगकर्ता इंटरफेस को लागू करता है।

प्रत्येक एप्लिकेशन के दृश्यों के पीछे एक मैसेजिंग सिस्टम होता है, जहां प्रत्येक विंडो अन्य विंडो या ईवेंट श्रोताओं को ईवेंट भेज सकती है - यह संदेश कतार में एक संदेश जोड़कर लागू किया जाता है। एक मुख्य लूप है जो हमेशा इस संदेश कतार को देखता है और फिर श्रोताओं को संदेश (या घटनाओं) भेज रहा है।

माइक्रोसॉफ्ट विंडोज में विकिपीडिया लेख संदेश लूप एक बुनियादी विंडोज प्रोग्राम का उदाहरण कोड दिखाता है - और जैसा कि आप सबसे बुनियादी स्तर पर देख सकते हैं एक विंडोज प्रोग्राम सिर्फ "संदेश पंप" है।

तो, यह सब एक साथ खींचने के लिए। UI का समर्थन करने के लिए डिज़ाइन किया गया विंडोज़ प्रोग्राम एक सेवा के रूप में कार्य नहीं कर सकता है, क्योंकि यह यूआई समर्थन को सक्षम करने के लिए हर समय चलने वाले संदेश लूप की आवश्यकता है। यदि आप इसे एक सेवा के रूप में वर्णित के रूप में कार्यान्वित करते हैं, तो यह आंतरिक अतुल्यकालिक घटना से निपटने में सक्षम नहीं होगा।


6

में कॉम , संदेश पंप serialises और de-serialises संदेशों अपार्टमेंट के बीच भेजा है। एक अपार्टमेंट एक मिनी प्रक्रिया है जिसमें COM घटकों को चलाया जा सकता है। अपार्टमेंट्स सिंगल थ्रेडेड और फ्री थ्रेडेड मोड में आते हैं। सिंगल थ्रेडेड अपार्टमेंट मुख्य रूप से COM घटकों के अनुप्रयोगों के लिए एक विरासत प्रणाली है जो मल्टी-थ्रेडिंग का समर्थन नहीं करते हैं। वे आम तौर पर विज़ुअल बेसिक के साथ उपयोग किए जाते थे (क्योंकि यह बहु-थ्रेडेड कोड का समर्थन नहीं करता था) और विरासत अनुप्रयोग।

मुझे लगता है कि Word के लिए संदेश पंप आवश्यकता COM API या अनुप्रयोग के कुछ हिस्सों से उपजी है जो थ्रेड सुरक्षित नहीं है। ध्यान रखें कि .NET थ्रेडिंग और गारबेज कलेक्शन मॉडल बॉक्स से बाहर COM के साथ अच्छी तरह से नहीं खेलते हैं। COM में एक बहुत ही सरल कचरा संग्रहण तंत्र और थ्रेडिंग मॉडल है जो आपको COM तरीके से काम करने की आवश्यकता है। मानक कार्यालय PIA का उपयोग करना अभी भी आपको COM ऑब्जेक्ट संदर्भों को स्पष्ट रूप से बंद करने की आवश्यकता है, इसलिए आपको बनाए गए प्रत्येक COM हैंडल का ट्रैक रखने की आवश्यकता है। यदि आप सावधान नहीं हैं, तो पीआईए पर्दे के पीछे सामान भी बनाएंगे।

.NET- COM एकीकरण एक संपूर्ण विषय है जो अपने आप में है, और इस विषय पर लिखी गई पुस्तकें भी हैं। यहां तक ​​कि एक इंटरैक्टिव डेस्कटॉप एप्लिकेशन से ऑफिस के लिए COM एपीआई का उपयोग करने के लिए आपको हुप्स के माध्यम से कूदना और यह सुनिश्चित करना होगा कि संदर्भ स्पष्ट रूप से जारी किए गए हैं।

कार्यालय को थ्रेड-असुरक्षित माना जा सकता है, इसलिए आपको प्रत्येक थ्रेड के लिए Word, Excel या अन्य Office अनुप्रयोगों की एक अलग आवृत्ति की आवश्यकता होगी । आपको शुरुआती ओवरहेड को उकसाना होगा या एक थ्रेड पूल को बनाए रखना होगा। एक थ्रेड पूल को सावधानीपूर्वक परीक्षण करना होगा ताकि यह सुनिश्चित हो सके कि सभी COM संदर्भ सही ढंग से जारी किए गए थे। यहां तक ​​कि उदाहरणों को शुरू करने और बंद करने के लिए आपको यह सुनिश्चित करने की आवश्यकता है कि सभी संदर्भ सही ढंग से जारी किए गए हैं। आपके i को डॉट करने में विफलता और आपके टी को यहां पार करने से बड़ी संख्या में मृत COM ऑब्जेक्ट और यहां तक ​​कि वर्ड के पूरे चलने वाले इंस्टेंस भी लीक हो जाएंगे।


1
आपके उत्तर में कुछ गलतियाँ हैं। 3 प्रकार के एपार्टमेंट हैं- एसटीए (सिंगल थ्रेडेड), एमटीए (मल्टी थ्रेडेड) और एनटीए (न्यूट्रल थ्रेडेड)। नि: शुल्क थ्रेडेड का उपयोग एक घटक का वर्णन करने के लिए किया जाता है जो मुक्त थ्रेडेड मार्शेलर को एकत्रित करता है, एक मुक्त थ्रेड ऐप्पल जैसी कोई चीज नहीं है। COM STAs से संवाद करने के लिए संदेशों का उपयोग करता है। MTA में रहने वाले घटकों के लिए (या जो मुक्त थ्रेडेड मार्शेलर को एकत्रित करते हैं) कोई संदेश लूप आवश्यक नहीं है। AFAIK - lpc का उपयोग RPC थ्रेड पूल से थ्रेड को कॉल करने से डेटा को मार्शेल करने के लिए किया जाता है जो वास्तव में विधि को आमंत्रित करता है।
क्विक्सवर


0

मुझे लगता है कि इस चैनल 9 चर्चा की एक अच्छी व्याख्या है:

खिड़की के संचार की यह प्रक्रिया तथाकथित विंडोज मैसेज पंप द्वारा संभव है। संदेश पंप को एक इकाई के रूप में सोचें जो एप्लिकेशन विंडो और डेस्कटॉप के बीच सहयोग को सक्षम करता है।


2
वाह ... यह एक भयानक और भ्रामक उद्धरण है। (एक "संस्था"? एर्र। नहीं।)
होगन

4
एंटिटी - ऑब्जेक्ट: कुछ ऐसा जो मौजूद है या जिसे एक अलग ऑब्जेक्ट एनकार्टा
मैथ्यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.