2010-12-27 7 views
17

में संसाधित किया गया है मेरे पास ManualResetEvent है। एक बिंदु पर, मैं उस घटना पर WaitOne का उपयोग कर प्रतीक्षा करता हूं। मेरे आश्चर्य के लिए, मुझे WaitOne में OnPaint ईवेंट प्राप्त हुआ। यह अक्सर भी होता है।यह कैसे संभव है: ऑनपेंट को वेटऑन

स्टैक ट्रेस इस तरह दिखता है:

alt text

मैं समझ गया कि एक WaitOne वर्तमान धागा ब्लॉक कर देगा और किसी भी अन्य कोड घटना आग जब तक निष्पादित करने के लिए अनुमति नहीं होगी।

कोई बता सकता है कि यहां क्या होता है?

उत्तर

20

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

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

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

यह सुनिश्चित करने के लिए कि आपको कोई समस्या नहीं आती है, आपको अपने प्रोग्राम को पुन: स्थापित करने की आवश्यकता है। मुख्य धागे को अवरुद्ध न करने पर ध्यान केंद्रित करना बहुत महत्वपूर्ण है। जब आपके पास अपने निपटान में पृष्ठभूमिवर्कर वर्ग या नियंत्रण। BginginInvoke() है, तो यह बहुत ही कम आवश्यकता है। किसी प्रकार के अजीब कारण के लिए म्यूटेक्स वर्ग इस तरह के पंपिंग नहीं करता है, यह एक और तरीका हो सकता है। यद्यपि यदि आप करते हैं तो डेडलॉक कोने के आसपास छिप रहा है।

+0

आपके उत्तर हमेशा एक अंतर्दृष्टि रखते हैं, फिर से कुछ नया सीखते हैं। – BrokenGlass

+0

कारण मैं इंतजार कर रहा हूं क्योंकि मैं नेटवर्क यातायात को पूरा करने की प्रतीक्षा कर रहा हूं। सर्वर यूआई बनाने के लिए आवश्यक डेटा प्रदान करता है। विशेष रूप से, मैं एक आलसी दृश्य सूची आलसी लोड कर रहा हूँ। जब एक पंक्ति को देखने में आता है जिसमें मेरे पास डेटा नहीं है, तो मुझे उस डेटा को पेंट पर प्रतिक्रिया करने में सक्षम होने की आवश्यकता है। यह डिजाइन द्वारा है। मैं देखूंगा कि 'म्यूटेक्स' वर्ग मदद करता है या नहीं। यदि आपके पास अन्य सुझाव हैं, तो निश्चित रूप से उनका स्वागत है। –

+0

बस इसे दूसरी तरफ करें। डेटा का आगमन पेंट इवेंट को प्रेरित कर सकता है। Control.BeginInvoke और अमान्य()। एसीआई/प्रतीक्षा के साथ सी # 5 में यह बहुत आसान होगा। यदि आवश्यक हो तो एक राज्य मशीन का प्रयोग करें। –

3

मैंने इस व्यवहार को lock() कथन के लिए भी देखा है। जाहिर है। नेट फ्रेमवर्क थ्रेड क्लास यूआई थ्रेड पर लॉक की प्रतीक्षा करते समय एक संदेश लूप शुरू करता है। यह सिर्फ बता रहा है कि क्या हो रहा है। विरासत एसटीए COM वस्तुओं के साथ काम करते समय deadlocks को रोकने के लिए तर्क हो सकता है। मुझे इसे रोकने के तरीके से अवगत नहीं है।

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