2010-10-25 9 views
7

यह कैसे संभव है? मेरे पास विंडोज़ फॉर्म नियंत्रण है, जो इस फॉर्म में निहित WebBrowser नियंत्रण के साथ System.Windows.Forms.Form से लिया गया है। Webbrowser ऑब्जेक्ट उदाहरण फॉर्म के निर्माता (InitializeComponent() विधि में) बनाया गया है। फिर पृष्ठभूमि धागे में मैं WebBrowser की सामग्री के साथ छेड़छाड़ करता हूं, और मैंने पाया कि कुछ मामलों में Form.InvokeRequired == झूठी, जबकि WebBrowser.InvokeRequired == सत्य। यह कैसे हो सकता है?आमंत्रण की आवश्यकता == झूठी और निमंत्रण निहित नियंत्रण की आवश्यकता == सत्य

+0

क्या यह प्रपत्र या समापन के दौरान या हर समय होता है? –

+0

ऐसा तब होता है जब फ़ॉर्म पहले ही बनाया गया है, लेकिन दिखाया नहीं गया है (संपूर्ण रूप, न केवल ब्राउज़र)। मैं सृजन के बाद सही फॉर्म नहीं दिखाता हूं। –

उत्तर

9

Form.InvokeRequired फॉर्म दिखाए जाने से पहले false देता है।

मैं एक साधारण परीक्षण किया:, झूठी InvokeRequired:, InvokeRequired यह सच है: सहायक के साथ

Form2 f2 = new Form2(); 
Thread t = new Thread(new ThreadStart(() => PrintInvokeRequired(f2))); 
t.Start(); 
t.Join(); 

f2.Show(); 

t = new Thread(new ThreadStart(() => PrintInvokeRequired(f2))); 
t.Start(); 
t.Join(); 

private void PrintInvokeRequired(Form form) 
{ 
    Console.WriteLine("IsHandleCreated: " + form.IsHandleCreated + ", InvokeRequired: " + form.InvokeRequired); 
} 

उत्पादन

IsHandleCreated है झूठी
IsHandleCreated : सही

भी ध्यान रखें कि यह कुछ हद तक MSDN पर प्रलेखित है:

नियंत्रण के हैंडल करता है नहीं अभी तक मौजूद हैं, InvokeRequired जब तक यह एक नियंत्रण या रूप एक है कि पाता है नियंत्रण की मूल श्रृंखला खोज विंडो हैंडल। यदि कोई उपयुक्त हैंडल पाया जा सकता है, InvokeRequired विधि झूठी रिटर्न देता है।

इसका मतलब है कि InvokeRequired झूठी लौटा सकते हैं या आह्वान आवश्यकता नहीं है, (कॉल एक ही धागे पर होता है) या यदि नियंत्रण एक अलग धागे पर बनाया गया था, लेकिन नियंत्रण के संभाल अभी तक नहीं बनाया गया है ।

मामले में जहां नियंत्रण के हैंडल अभी तक नहीं बनाया गया है में, आप बस गुण, पद्धतियों, या घटनाओं पर नियंत्रण नहीं बुलाना चाहिए। यह हो सकता है कि नियंत्रण धागा पृष्ठभूमि थ्रेड पर बनाया गया है, संदेश पंप के बिना पर नियंत्रण को अलग करना और एप्लिकेशन अस्थिर बनाना।

आप द्वारा भी IsHandleCreated का मान रिटर्न एक पृष्ठभूमि धागे पर झूठी InvokeRequired जाँच इस मामले के खिलाफ की रक्षा कर सकते हैं। यदि नियंत्रण हैंडल अभी तक बनाया गया है, तो आपको तब तक प्रतीक्षा करनी होगी जब तक कि को Invoke या BeginInvoke कॉल करने से पहले बनाया गया हो। आमतौर पर, यह एक पृष्ठभूमि धागा आवेदन ( Application.Run में के रूप में के लिए प्राथमिक रूप के निर्माता में बनाई गई है केवल अगर (नई MainForm()) होता है, रूप से पहले दिखाया गया है या Application.Run बुलाया गया।

आपका समाधान IsHandleCreated के लिए भी जांचना है।

संपादित करें:
Handle किसी भी समय WebBrowser नियंत्रण या बाह्य रूप में आंतरिक पर बनाया जा सकता है। यह स्वचालित रूप से मूल रूप से हैंडल नहीं बनाता है।

Button1: उत्पादन के साथ

public Form2() 
{ 
    InitializeComponent(); 

    Button button1 = new Button(); 
    this.Controls.Add(button1); 

    Console.WriteLine("button1: " + button1.IsHandleCreated + " this: " + this.IsHandleCreated); 
    var tmp = button1.Handle; // Forces the Handle to be created. 
    Console.WriteLine("button1: " + button1.IsHandleCreated + " this: " + this.IsHandleCreated); 
} 

:

मैं एक उदाहरण के लिए बनाए गए झूठे यह झूठा
Button1: यह सच है यह: गलत

+0

लेकिन मैं निहित नियंत्रण (WebBrowser) InvokeRequired संपत्ति की जांच करता हूं, और यह सही है, जबकि फॉर्म .InvokeRequired गलत है। लॉजिक इनवेक के मुताबिक पदानुक्रम में सभी बाल नियंत्रणों की आवश्यकता होती है यदि माता-पिता के नियंत्रण के समान ही धागे में बाल नियंत्रण बनाए जाते हैं तो इनोवोक को मूल नियंत्रण के लिए आवश्यक होना चाहिए। और मेरी स्थिति में वेबब्रोसर नियंत्रण फॉर्म के कन्स्ट्रक्टर में बनाया गया है यानी वे एक थ्रेड में बनाए गए थे। शायद हमारे पास WebBrowser नियंत्रण का कुछ विशिष्ट व्यवहार है? –

+1

@ डिमिट्री: नहीं। नियंत्रण के हैंडल को मूल रूप से हैंडल के हैंडल से बनाया जा सकता है। मैंने एक उदाहरण के साथ अपना जवाब अपडेट किया है। –

+0

ओह, धन्यवाद! बहुत दिलचस्प है, और यह सब कुछ स्पष्ट करता है! –

0

मैं इस अजीब व्यवहार की जांच कर रहा हूं। मुझे विभिन्न धागे से कुछ नियंत्रण संचालित करने की आवश्यकता है (उदाहरण के लिए मेजबान से जुड़े डिवाइस के बारे में जानकारी दिखाएं या अलग-अलग डिवाइसों के आधार पर क्रियाएं ट्रिगर करें)।

यह लिंक मुझे एक अच्छा संकेत दिया था: http://csharpfeeds.com/post/2898/Control.Trifecta_InvokeRequired_IsHandleCreated_and_IsDisposed.aspx

मैं अभी भी कैसे एमएस लोग अपने सामान का उपयोग करने के उद्देश्य से पता नहीं है (और कई पहलुओं में सहमत नहीं हूँ), लेकिन, एक में आवेदन मुझे निम्नलिखित गंदा और गंदी कामकाज करना था:

  • मुख्य धागे में नियंत्रण/रूप बनाएं (सुनिश्चित करें कि यह मुख्य धागा है)।
  • उसी प्रक्रिया में, नियंत्रण हैंडल की जांच करें। यह सरल चेक इसे सही धागे में और बनाने के लिए मजबूर करेगा!

कितना बदसूरत है, है ना? मैं जानना चाहता हूं कि किसी और के पास ऐसा करने का बेहतर तरीका है या नहीं।

_my_control = new ControlClass(); 
_my_control.Owner = this; 

IntPtr hnd; 

// Force Handle creation by reading it. 
if (!_my_control.IsHandleCreated || _my_control.Handle == IntPtr.Zero) 
    hnd = _my_control.Handle; 

(इस कुछ पुरानी पोस्ट में पोस्ट करने के लिए खेद है, लेकिन मैंने सोचा कि यह किसी के लिए उपयोगी हो सकता है)।

+0

ध्यान दें कि आपके उदाहरण में, हैंडल वास्तव में चेक _my_control.Handle == IntPtr.Zero द्वारा बनाया जाएगा। एक छोटी विधि _myControl = नया ControlClass {स्वामी = यह} हो सकती है; var temp = _myControl.Handle; –

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