2011-02-08 9 views
8

मैंने एक टन खोजा है, लेकिन मुझे अपनी विशिष्ट समस्या से संबंधित कुछ भी नहीं मिल रहा है।सी # विंडोज फॉर्म आवेदन - एक और धागे और कक्षा से जीयूआई अद्यतन?

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

लेकिन मैं वास्तव में क्या करना चाहता हूं क्लाइंट से कोड का आह्वान करने में सक्षम हो सकता है जो मेरे मेनयूआई उदाहरण पर चीजें करेगा। मैं यह कैसे कर सकता हूँ?

इसके अलावा, अगर कोई कोड के विशिष्ट भाग चाहता है तो मैं इसे पोस्ट करने के बारे में बेहतर समझने में सहायता के लिए पोस्ट कर सकता हूं।

सर्वश्रेष्ठ संबंध!

उत्तर

17

Control वर्ग के InvokeRequired चेक, और अगर यह सच है, तो Invoke फोन और एक प्रतिनिधि (आमतौर पर एक गुमनाम विधि) करता है कि क्या आप ग्राहक के धागे पर क्या करना चाहते हैं में गुजरती हैं।

उदाहरण:

public void DoWork(Form form) 
{ 
    if (form.InvokeRequired) 
    { 
     // We're on a thread other than the GUI thread 
     form.Invoke(new MethodInvoker(() => DoWork(form))); 
     return; 
    } 

    // Do what you need to do to the form here 
    form.Text = "Foo"; 
} 
+0

चूंकि मैं यूआई की तुलना में एक अलग वर्ग में हूं, इसलिए मैं चर "फ़ॉर्म" कैसे प्राप्त करूं जो वर्तमान में चल रहे फॉर्म को इंगित करता है ताकि इसे DoWork में पास किया जा सके? –

+0

कुछ ऑटोप्रोपर्टी-जैसी वाक्य रचनात्मक चीनी इस तरह के बॉयलरप्लेट के लिए अच्छा नहीं होगा? – MusiGenesis

+1

@firstEncounter: आप अपनी कक्षा में एक कन्स्ट्रक्टर जोड़ सकते हैं जो पैरामीटर के रूप में 'फॉर्म' लेता है, फिर संदर्भ को क्लास-स्तरीय चर में संग्रहीत करता है। – MusiGenesis

4

हाँ, आपको लगता है कि एक पैरामीटर के रूप MainUI रूप ले लेता है अपनी कक्षा में एक निर्माता जोड़ सकते हैं। ऐसा करने का यह तेज़ तरीका है, लेकिन यह आपकी कक्षा से मेनयूआई तक "पिछड़ा" निर्भरता पेश करता है, जहां सिद्धांत रूप में, कोई निर्भरता आवश्यक नहीं है।

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

और ऐसा करने पर, यह वह निर्माण है जिसका मैं अपने सभी कोड में उपयोग कर रहा हूं।

class NetworkEventArgs : EventArgs { /* defined class here */ } 
private void NetworkEventHandler(object sender, NetworkEventArgs e) 
{ 
    Invoke((MethodInvoker) delegate { 
     myTextBox.Text = e.Message; 
    } 
} 

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

+0

मेरे कोड को संरचित करने का यह तरीका वास्तव में मेरे लिए अच्छा काम करता है। मैं बस जोड़ना चाहता हूं कि मुझे Invoke/MethodInvoker के साथ परेशानी थी, मेरा जीयूआई बस लटका होगा। मैंने इसे BeginInvoke (नया MyDelegate (MyDelegateMethod), myParam) में बदल दिया; अब महान काम करता है। –

0

आप एक घटना अपने clientThread वर्ग

को परिभाषित करने और MainForm में इसे संभाल कर सकते हैं जब clientThread बारे में पता MainForm की जरूरत है कुछ करने के लिए (जैसे कुछ नियंत्रण स्थिति अद्यतन) आप घटना

तो MainForm हो जाता है सक्रिय किया जाना चाहिए घटना से पैरामीटर और अद्यतन फ़ंक्शन

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