2011-03-04 23 views
7

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

यदि हम Form.Show() के विरोध में Application.Run(Form) का उपयोग करते हैं तो प्रदर्शन प्रदर्शन में वृद्धि हो सकती है? क्या ऐसा करने के लिए इससे अच्छा तरीका है? कृपया बताएं क्यों या क्यों नहीं।

+2

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

उत्तर

13

Application.Run() का उपयोग न करें जबतक कि आप यह नहीं जानते कि यह क्या करता है। और, एक बार जब आप जानते हैं कि यह क्या करता है, तो आपको पता चलेगा कि कार्यक्रम की शुरुआत के अलावा आपको इसका उपयोग क्यों नहीं करना चाहिए।

आवेदन। रून एक संदेश पंप शुरू करता है। यह किसी भी जीयूआई प्रोग्राम का दिल है, और खिड़की को संदेशों को प्राप्त करने में क्या सक्षम बनाता है, जो इसे घटनाओं को आग लगाने और सामान करने की अनुमति देता है। आपके पास दो संदेश पंप नहीं हो सकते हैं, क्योंकि इससे कोई अर्थ नहीं आता है।

(हाँ, मुझे पता है कि आप दो संदेश पंप हो सकता है, लेकिन क्यों आप कभी भी चाहते हैं? यह पर्याप्त होने एक पंप मुश्किल है!)

अपने असली प्रश्न के रूप में (कैसे क्या मैं अपने जीयूआई थ्रेड पर सामान नहीं करता), यह थोड़ा और जटिल है। सबसे सरल जवाब "धागे का उपयोग करें" है।

  1. अन्य धागे से नियंत्रण में हेरफेर करने की कोशिश मत करो: के बाद से मैं अपनी स्थिति का विवरण पता नहीं है, मैं केवल कुछ सामान्य सलाह दे सकते हैं। सबसे अच्छा, यह काम नहीं करेगा। सबसे बुरी स्थिति में, यह आपके घर को आग लगाएगा (ठीक है, शायद वह बुरा नहीं है। लेकिन, ऐसा मत करो।)। इसके बजाय, आपको Invoke विधियों की आवश्यकता है। एक उदाहरण नीचे प्रदान किया जाएगा।

  2. अपने जीयूआई थ्रेड पर लंबी चल रही प्रक्रियाएं न चलाएं। छोटी चीजें ठीक हैं, लेकिन कुछ भी जो आधे सेकेंड से अधिक समय ले सकता है शायद सबसे अच्छा दूसरे थ्रेड पर ऑफलोड हो जाता है।

  3. अपने वर्कर थ्रेड से वापस अपने जीयूआई थ्रेड पर संवाद करने के लिए ईवेंट का उपयोग करें।

    delegate void VoidDelegate(); 
    
    List<int> results; 
    bool cancelWork = false; 
    
    void DoWork() { 
        int calc; 
        results = new List<int>(); 
    
        for(int i = int.MinValue ; i < int.MaxValue; i+=10) { 
         if(cancelWork) break; 
         results.Add(i); 
        } 
    
        this.Invoke(new VoidDelegate(WorkFinished)); 
    } 
    
    void Button1_Click(object sender, EventArgs e) { 
        button1.Enabled = false; 
        button2.Enabled = true; 
        cancelWork = false; 
        Thread t = new Thread(DoWork); 
        t.Start(); 
    } 
    
    void Button2_Click(object sender, EventArgs e) { 
        button2.Enabled = false; 
        cancelWork = true; 
    } 
    
    void WorkFinished() { 
        button1.Enabled = true; 
        button2.Enabled = false; 
        textBox1.Text = results.Count.ToString(); 
    } 
    

    जाहिर है, यह एक काल्पनिक उदाहरण है लेकिन यह मेरा उद्देश्य में कार्य करता है,:

यहाँ कैसे एक कार्यकर्ता धागा चलाने के लिए का एक उदाहरण है।

यह काल्पनिक रूप दो बटन, button1 ("रन") और button2 ("रद्द करें") एक पाठ बॉक्स, textbox1 हो सकते हैं। बटन 2 को अक्षम करना शुरू करना चाहिए (Enabled = false)।

जबकि कार्यकर्ता थ्रेड चल रहा है, उपयोगकर्ता "रद्द करें" बटन (button2 मेरे उदाहरण में) सहित किसी भी अन्य नियंत्रण के साथ बातचीत कर सकता है। एक बार यह खत्म होने के बाद, यह InvokeWorkFinished फ़ंक्शन है, जो परिणाम प्रदर्शित करता है (और अन्यथा राज्य को साफ़ करता है)।

5

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

आप एप्लिकेशन को कॉल कर सकते हैं। किसी अन्य थ्रेड से चलाएं, लेकिन फिर आपके पास दो UI थ्रेड होंगे जिन्हें आपको सिंक्रनाइज़ करने की आवश्यकता है। आप यह सुनिश्चित किए बिना सामान को पास नहीं कर सकते कि आप विवाद की स्थिति में नहीं पहुंच पाएंगे।

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