/ / C # GUI हैंडल समस्याओं को बंद करें - c #, मल्टीथ्रेडिंग, उपयोगकर्ता-इंटरफ़ेस

सी # जीयूआई समस्याओं को बंद करें - सी #, मल्टीथ्रेडिंग, उपयोगकर्ता-इंटरफ़ेस

मुझे एक सिस्टम मिलता है।जब मैं खोज करने से पहले अपना ऐप बंद कर देता हूं तो InvalidOperationException त्रुटि होती है। जब मैं Form1_FormClosing पर बंद करता हूं तो मैं अपने सभी थ्रेड को गर्भपात के लिए कहता हूं। एक थ्रेड में इसे अंतिम रूप दिया गया है जो एक प्रतिनिधि फ़ंक्शन को कॉल करता है जो अपने टेक्स्ट को बदलने के लिए प्रपत्र में से किसी एक नियंत्रण को बताता है। जब ऐसा होता है तो मुझे इसके अतिरिक्त अपवाद मिलता है "अतिरिक्त जानकारी: Invoke या BeginInvoke को एक नियंत्रण पर नहीं बुलाया जा सकता जब तक कि विंडो हैंडल नहीं बनाया गया है।"

इसे ठीक करने के लिए मुझे क्या करना होगा? मैं एक isClosing ध्वज जोड़ सकता है और पाठ को अपडेट करने से पहले इसे जांच सकता है लेकिन यह एक हैक की तरह लगता है और समस्या को मास्क करता है। मैं इसे सही तरीके से कैसे हल करूं?

उत्तर:

उत्तर № 1 के लिए 1

ऐसा इसलिए हो रहा है क्योंकि प्रबंधित नियंत्रण का निपटारा किया जा रहा है और अब इसके हैंडल नहीं हैं, लेकिन आपने विंडो को बंद नहीं किया है, इसलिए आप इसे अभी भी देखते हैं।

आप एक ऐसा फंक्शन बना सकते हैं, जो रैप होगा Invoke कॉल और के लिए जाँच करेगा IsHandleCreated कॉल करने से पहले Invoke। अगर IsHandleCreated गलत है, आप कॉल नहीं कर सकते Invoke और आप कॉल को अनदेखा कर सकते हैं।

public static class ControlExtensions
{
public static TResult InvokeEx<TControl, TResult>(this TControl control,
Func<TControl, TResult> func)
where TControl : Control
{
if (!control.IsHandleCreated)
return default(T);

if (control.InvokeRequired)
return (TResult)control.Invoke(func, control);
else
return func(control);
}

public static void InvokeEx<TControl>(this TControl control,
Action<TControl> action)
where TControl : Control
{
control.InvokeEx(c => { action(c); return c; });
}
}

तो अब बस किसी भी लपेटो Invokeके साथ अपने धागे से InvokeEx और यह तब नियंत्रित होगा जब एक नियंत्रण को निपटाया गया है और अब एक संभाल नहीं है।

this.InvokeEx(c => c.label1.Text = "Hello world");

उत्तर № 2 के लिए 1

मैं शमूएल से सहमत हूँ, लेकिन जाँच भी करूँगा IsDisposed:

void Handler()
{
if (ctrl.IsDisposed || !ctrl.IsHandleCreated) return;
if (ctrl.InvokeRequired)
Invoke(...);
else {
...
}
}