2010-05-04 15 views

उत्तर

13

(सरलीकरण आगे)

एक यूआई धागा एक एकल थ्रेडिंग अपार्टमेंट धागा है कि विभिन्न यूजर इंटरफेस वस्तुओं को बनाने के (Winforms में, इसका मतलब है नियंत्रण) किया जाता है। सम्मेलन और शासन के अनुसार, एक नियंत्रण केवल को बनाने के लिए उपयोग किए गए थ्रेड के भीतर से पहुंचा जा सकता है; अन्यथा ऐसा करना अप्रत्याशित परिणाम उत्पन्न कर सकता है, दृश्य अजीबता से सभी तरह से दुर्घटनाग्रस्त हो सकता है।

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

+2

+1 यह उल्लेख करने के लिए कि आप यह कर सकते हैं, लेकिन यह शायद ही कभी चीजों को किया जाना चाहिए ... –

+0

तो जब आप एक नया थ्रेड() प्रारंभ करें() STATHread के अंदर क्या करें? –

+0

@ ग्रिवर: यह एक नया धागा शुरू करता है, लेकिन यह यूआई थ्रेड से पूरी तरह से अलग है। एक नया थ्रेड शुरू करना कहीं भी एक नया, असंबंधित धागा बनाता है। –

0

शुद्धता के लिए संपादित:

वहाँ विण्डोज़ फॉर्म्स और WPF के लिए इसी तरह की अवधारणा में सक्रिय आवेदन प्रति एक यूआई धागा है।

यानी: जब आप ऐप शुरू करते हैं, तो एक धागा होता है, यह यूआई थ्रेड बन जाता है जब एप्लिकेशन। रुन (नया फॉर्म 1()); कहा जाता है।

यदि आप एप्लिकेशन करने का प्रयास करते हैं। रुन (नया फॉर्म 2()); रनटाइम पर आपको "System.InvalidOperationException: एक थ्रेड पर दूसरा संदेश लूप प्रारंभ करना एक वैध ऑपरेशन नहीं है। इसके बजाय Form.ShowDialog का उपयोग करें।"

यदि आपको वास्तव में एक ही धागे को साझा करने के लिए दो अलग-अलग रूपों की आवश्यकता नहीं है, तो आपको एक नया धागा बनाना होगा, फिर एप्लिकेशन को कॉल करें। रुन (नया माईफॉर्म()) इत्यादि। यह आम नहीं है।

+1

यह सच नहीं है। विंडोज फॉर्म में विभिन्न रूप, सभी ** ** ** थ्रेड का उपयोग करते हैं। संदेश पंप उन्हें सभी उत्तरदायी बनाता है। –

+0

मैंने इसे उलट दिया था, मोडल संवादों को एक नए थ्रेड की आवश्यकता होती है, मॉडलस संवाद * को * एक नया धागा की आवश्यकता नहीं होती है। बिंदु अभी भी खड़ा है कि जब उनके द्वारा एक नया फॉर्म लॉन्च किया जाता है तो सामान्य धागे ui धागे बन सकते हैं। – David

+0

यह अभी भी असत्य है। एक संदेश धागा शुरू करने के लिए विशेष देखभाल के बिना, एक नए धागे से "एक फॉर्म लॉन्च करना", डिफ़ॉल्ट रूप से एसटीए की कमी के कारण सभी प्रकार की समस्याओं (ज्यादातर मामलों में) दुर्घटनाग्रस्त होने का कारण बनता है। –

7

एक यूआई धागा विशेषताओं है कि यह विशेष बनाने की एक संख्या है:

  • विंडोज धागा के साथ जुड़े एक संदेश कतार है। यह थ्रेड पर पहली विंडो बनने के साथ ही होता है।
  • थ्रेड एक संदेश लूप चलाता है, जिससे विंडोज़ विंडोज़ को संदेशों को प्रेषित करने की इजाजत देता है। जैसे ही आप एप्लिकेशन को कॉल करते हैं, संदेश लूप बन जाता है। रुन()।
  • COM थ्रेड पर प्रारंभ किया गया था, एकल-थ्रेडेड अपार्टमेंट का अनुरोध किया गया था। कई विंडोज़ सुविधाओं को ठीक तरह से काम करने की अनुमति देने के लिए एक एसटीए आवश्यक है, जो डिज़ाइन द्वारा थ्रेड-सुरक्षित नहीं हैं। COM यह सुनिश्चित करता है कि इन सुविधाओं को हमेशा थ्रेड-सुरक्षित तरीके से बुलाया जाता है, जो आवश्यकतानुसार एक कार्यकर्ता थ्रेड से एसटीए थ्रेड तक कॉल को मार्शल करते हैं। इन सुविधाओं के उदाहरण ड्रैग + ड्रॉप, क्लिपबोर्ड, शैल डायलॉग (ओपनफाइलडियलॉग इत्यादि), वेबब्राउज़र जैसे एक्टिवएक्स कंट्रोल, सेटविंडोशूकएक्स द्वारा सेट की गई विंडो हुक, स्क्रीन रीडर, यूआई ऑटोमेशन प्रदाताओं द्वारा उपयोग की जाने वाली एक्सेसिबिलिटी प्रदाताओं। सभी बाहरी कोड, इनमें से कोई भी थ्रेड-सुरक्षित नहीं है।
  • धागा किसी भी ऑपरेशन पर कभी भी अवरुद्ध नहीं होता है, यह उत्तरदायी रहता है ताकि यह उपयोगकर्ता इंटरफ़ेस को उत्तरदायी और COM मार्शलिंग अनुरोधों को बहने के लिए आवश्यकतानुसार विंडोज संदेशों को प्रेषित कर सके। WaitHandle.WaitAny() को कॉल करना उदाहरण के लिए स्पष्ट रूप से प्रतिबंधित है और अपवाद उत्पन्न करता है। सीएलआर में प्रतीक्षाऑन() और lock के लिए विशिष्ट समर्थन है, जो डेडलॉक से बचने के लिए एक आंतरिक संदेश लूप पंप कर रहा है।

किसी प्रक्रिया का स्टार्टअप थ्रेड लगभग हमेशा यूआई थ्रेड के रूप में चुना जाता है, हालांकि यह एक कठिन आवश्यकता नहीं है। एसटीए राज्य मुख्य() विधि पर [STAThread] विशेषता द्वारा चुना जाता है।

आप यह सुनिश्चित करके यूआई थ्रेड बना सकते हैं कि उपर्युक्त आवश्यकताओं को पूरा किया जाए। यही कारण है कि एक Winforms अनुप्रयोग में ऐसा दिखाई दे सकता:

var ui = new Thread(() => { Application.Run(new Form2()); }); 
    ui.SetApartmentState(ApartmentState.STA); 
    ui.Start(); 

कि एक दूसरे विंडो बनाता है, अपने स्वयं के यूआई धागे पर चल रहा है। इस व्यवस्था के साथ आपके पास एक आम समस्या यह है कि अब आपके पास दो अलग-अलग खिड़कियां हैं, वे एक-दूसरे से जुड़े नहीं हैं। दूसरी विंडो का स्वामित्व 1 के स्वामित्व में नहीं हो सकता है, इसका पहला जेड-ऑर्डर पहले से स्वतंत्र है। उपयोगकर्ता द्वारा सौदा करने में मुश्किल है। SystemEvents.UserPreferenceChanged इवेंट उल्लेखनीय है, यह अनिवार्य रूप से गलत घटना पर अपनी घटना को आग लग जाएगा और यह डेडलॉक का कारण बनने के लिए उपयुक्त है। WinForms के बहुत सारे इसे सब्सक्राइब करते हैं। दुर्लभ परिस्थितियों को छोड़कर, स्प्लैश स्क्रीन की तरह, यह उपयोगकर्ता इंटरफ़ेस में भी सुधार नहीं करता है।

+0

मुझे आपका विस्तृत उत्तर पसंद है। –

संबंधित मुद्दे