मेरे पास एक बड़े ऐप के साथ कुछ थ्रेडिंग समस्याएं हैं जिन पर मैं काम कर रहा हूं (क्रॉस-थ्रेड अपवाद प्राप्त कर रहा हूं)। क्या थ्रेड नाम/आईडी ढूंढने का कोई तरीका है जिस पर एक विशेष नियंत्रण बनाया गया था?क्या नियंत्रण के मालिक धागे को खोजने का कोई तरीका है?
त्रुटि तब होती है जब मैं अपने नियंत्रण के नियंत्रण संग्रह में नया नियंत्रण जोड़ने का प्रयास करता हूं। मैं वास्तव में एक छोटा, पुनरुत्पादित नमूना नहीं बना सकता, इसलिए मैं इसे जितना संभव कर सकता हूं उतना ही वर्णन करूंगा।
मेरे पास एक मुख्य नियंत्रण है जो एक फॉर्म पर बैठता है, इसे _mainControl कहते हैं। इसके निर्माता में मैं एक और नियंत्रण का एक उदाहरण का दृष्टांत, की तरह कुछ
ChildControl _childControl = new ChildControl();
अब _childControl मौजूद है, लेकिन मैं अभी तक _mainControls संग्रह में जोड़ना नहीं है।
आखिरकार, _mainControl को एक ईवेंट अधिसूचना प्राप्त होती है कि मुझे नियंत्रण जोड़ना चाहिए। ईवेंट हैंडलर में मैं अगर this.InvokeRequired की जाँच करें और अगर ऐसा है, मैं हैंडलर आह्वान, निम्नलिखित की तरह कुछ:
AddControlEventHander(...)
{
if(InvokeRequired)
{
BeginInvoke(new MethodInvoker(AddControlEventHander);
return;
}
Controls.Add(_childControl);
}
अपवाद हमेशा Controls.Add ("क्रॉस-धागा आपरेशन मान्य नहीं पर फेंक दिया जाता है: "_item 'को थ्रेड के अलावा किसी थ्रेड से एक्सेस किया गया था जिसे" "बनाया गया था।
अब, मुझे समझ में नहीं आता कि यह कैसे संभव है। मैंने उसी थ्रेड पर _childControl बनाया है जिस पर _mainControl बनाया गया था। जब मैं डीबगिंग कर रहा हूं, तो थ्रेड विंडो को देखते समय, जब मैं नियंत्रण कॉल करता हूं तो वर्तमान थ्रेड नाम/आईडी समान होता है। जैसा कि _childControl जोड़ा गया था। हालांकि, मुझे सबसे ज्यादा भ्रमित करने वाली चीज _mainControl से निम्नलिखित कॉल हैं:
InvokeReuqired == false;
_childControl.InvokeRequired == false;
_childControl._item.InvokeRequired == true; //I made _item public just to try this and it returns true!
यह कैसे संभव है? क्या _childControl को एक थ्रेड पर बनाया जाना संभव है जबकि इसके बच्चे किसी अन्य तरीके से बनाए जाते हैं? _childControl के सभी बच्चे प्रारंभिकरण के दौरान बनाए जाते हैं, जैसा आमतौर पर किया जाता है।
यदि किसी के पास कोई सुझाव/सुझाव है कि क्या हो रहा है, तो कृपया मुझे बताएं।
धन्यवाद।
संपादित करें:
मामले में किसी को भी रुचि रखता है, मुझे पता चला क्या हो रहा था। मैं उत्सुक था कि कैसे एक धागे पर नियंत्रण बनाया जा सकता है और इसके बच्चों को एक और धागे पर बनाया गया है, भले ही InitializeComponent एक ही धागे पर किया गया हो। इसलिए, मुझे पता चला कि चार्ल्स ने नीचे सुझाए गए कोड के समान कोड का उपयोग करने के लिए कौन सा धागा बनाया था। एक बार मुझे पता था कि, मुझे कम से कम पता था कि किस धागे पर ध्यान केंद्रित करना है। तब मैंने बाल नियंत्रण के ऑनहैंडलक्रेटेड कार्यक्रम को तोड़ दिया और इस मुद्दे को पाया।
एक बात जो मुझे नहीं पता था कि नियंत्रण का संभाल तब बनाया जाता है जब नियंत्रण पहली बार दिखाई देता है, जब यह बनाया जाता है। तो एक धागा जिस पर नियंत्रण नहीं था, वह इसकी दृश्यता को सत्य बनाने की कोशिश कर रहा था। इसलिए मैंने यह देखने के लिए एक चेक जोड़ा कि क्या InvokeRequired और सोचा था कि यह चाल करेगा। हालांकि, कुछ जो मैंने वास्तव में उम्मीद नहीं की थी वह है कि कॉलिंग InvokeRequired नियंत्रण के हैंडल बनाएगा अगर यह अभी तक नहीं बनाया गया है! यह प्रभाव में गलत धागे पर नियंत्रण बनने का कारण बनता है और हमेशा InvokeRequired के लिए झूठी वापसी करता है। मैं नियंत्रण की हैंडल संपत्ति को छूकर इस के आसपास हो गया ताकि यह InvokeRequired कहलाए जाने से पहले बनाया गया हो।
मदद लोगों के लिए धन्यवाद :)
संकेत के लिए धन्यवाद। मैंने इसी तरह खोजा कि निर्दोष 'अगर (नियंत्रण। हैंडल! = शून्य) ... 'वास्तव में उस धागे पर नियंत्रण बनाता है! –
मेरा जवाब यहां देखें http://stackoverflow.com/questions/8331144/ensuring-that-child-controls-are-created-in-main-ui-thread/17054689#17054689 –