2010-03-18 10 views
5

मेरे पास एक विंडोज़ फॉर्म एप्लीकेशन (फॉर्म 1) है जो उपयोगकर्ता को अन्य फॉर्म (फॉर्मग्राफ) खोलने की अनुमति देता है। फॉर्मग्राफ ऐप खोलने के लिए मैं इसे खोलने वाले थ्रेड का उपयोग करता हूं।विंडोज थ्रेड दिखाने के तुरंत बाद मेरा थ्रेड समाप्त क्यों होता है?

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    myGraph.Show(); 
} 

मेरे समस्या myGraph बंद कर दिया है कि सही होने के बाद यह खुला है है:
यहाँ कोड है कि धागा चल रहा है है।
1) क्या किसी को पता है कि यह क्यों हो रहा है और myGraph कैसे खुला रहता है?
2) उपयोगकर्ता ने myGraph को बंद करने के बाद, मैं धागे को कैसे समाप्त कर सकता हूं?
बहुत धन्यवाद!

उत्तर

0

गैर-मुख्य धागे में फॉर्म नहीं बनाते और दिखाते हैं। इसे मुख्य रूप धागे में करें।

या ऐसा करते हैं:

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    Application.Run(myGraph); 
} 

लेकिन पहले संस्करण बेहतर

+0

यही वह करता है जो वह करता है। – TomTom

+0

ध्यान से पढ़ें: "मैं इसे खोलने वाले धागे का उपयोग करता हूं।" – Andrey

+0

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

0

एक सामान्य नियम के आप धागे से यूआई से छेड़छाड़ करने से बचना चाहिए के रूप में है (एक फार्म बनाने यूआई के लिए जोड़-तोड़ का एक प्रकार है) । आपको हमेशा मुख्य धागे से यूआई में हेरफेर करना चाहिए।

+0

फॉर्म निर्माण बिल्कुल नहीं है .... हेरफेर। – TomTom

+0

यदि आप यूआई के सिर्फ एक हिस्से के रूप में प्रपत्रों के बारे में सोचते हैं और यूआई के लिए कंटेनर नहीं है तो यह है। – dbemerlin

+0

यह अभी भी गलत है। बहु यूआई धागे के लिए बहुत अच्छे मामले हैं। – TomTom

0

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

आपको विधि में स्थानीय रूप से बजाय फॉर्म में ऑब्जेक्ट के लिए एक चर घोषित करना चाहिए, ताकि जब आप धागे से बाहर निकलेंगे तो यह जीवित रहेगा।

जब आप फॉर्म दिखाने के लिए तैयार होते हैं, तो आप मुख्य थ्रेड में निष्पादित विधि विधि बनाने के लिए Invoke विधि का उपयोग कर सकते हैं।

+0

उपयोगकर्ता क्या पूछता है नहीं। वह एक अलग यूआई थ्रेड में दूसरी विंडो खोलने के लिए वांछित में स्पष्ट है, जो - आकस्मिक रूप से - कभी-कभी वास्तव में अच्छे कारण होते हैं (व्यापार अनुप्रयोग इसके लिए जाने जाते हैं)। – TomTom

+1

@ टॉमटॉम: कृपया ओपी वास्तव में क्या चाहता है इसके बारे में फैसला करने की कोशिश न करें। यह स्पष्ट है कि वर्तमान में एक थ्रेड का उपयोग किया जाता है, लेकिन यह स्पष्ट नहीं है कि यह वास्तव में वांछित समाधान है। सिर्फ इसलिए कि ओपी कुछ मांगता है, इसका मतलब यह नहीं है कि यह सही समाधान है। अगर किसी ने कभी भी उत्तर दिया है कि क्या पूछा गया था, तो "हाँ" या "नहीं" के अलावा कई प्रश्नों का उत्तर नहीं दिया जा सका, क्योंकि वास्तव में सवाल पूछा गया था कि प्रश्न पूछकर क्या मतलब था। – Guffa

+0

कृपया ओपी के बारे में सत्तारूढ़ प्रयास करने की कोशिश न करें। अपनी पोस्ट पढ़ें। अपने उदाहरण का पालन करें और वह जो भी करने की कोशिश करता है उसे घटाएं। यह न मानें कि प्रोग्रामर एक जुआ बेवकूफ है। – TomTom

0

फॉर्म बंद हो रहा है क्योंकि धागा समाप्त हो गया है और इसलिए इसके resouces (फॉर्म) के साथ मुक्त किया जाता है। थ्रेड चलने के लिए आपको एक लूप

उदा।

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    myGraph.Show(); 
    while (myGraph.IsOpen) 
    { 
     //process incoming messages <- this could be fun on a thread.... 
    } 
} 

आप (समय समाप्त या एक बटन की तरह) IsOpen स्थापित करने की एक विधि की आवश्यकता होगी और स्पष्ट रूप से आप जब प्रपत्र बनाई गई है वास्तव में प्रपत्र की एक संपत्ति के रूप में IsOpen बना सकते हैं और सच करने के लिए यह सेट करना होगा ।

मैं यहां अन्य उपयोगकर्ताओं के समान ही जोड़ूंगा ... आपके पास मुख्य धागे का उपयोग न करने का एक अच्छा कारण होना चाहिए।

+0

यहां पर बहुत से लोग वास्तव में एकाधिक संदेश पंपों के एक बार नहीं जानते हैं - यह दर्द होता है। आरटीएफएम, दोस्तों। एक बहु थ्रेडेड यूआई करने के लिए वास्तव में अच्छे कारण हैं - मेरे पास 6 विंडोज़ के लिए 6 यूआई थ्रेड का उपयोग करने वाला एक है। कौन सा व्यस्त पुनर्भुगतान कर रहे हैं। यह पूरी तरह से समर्थित है। – TomTom

1

मुख्य समस्या यह है कि आप नए धागे में एक संदेश पंप स्थापित नहीं करते हैं।

चेक

Run multiple UI Threads

एक अच्छा सिंहावलोकन कैसे एक उच्च perforamnce उपयोगकर्ता से अधिक थ्रेड (प्रपत्र प्रति एक रूपों में से/समूह) का उपयोग इंटरफ़ेस को चलाने के लिए।

जो आप मूल रूप से याद करते हैं वह एप्लिकेशन के लिए कॉल है। अलग यूआई थ्रेड पर संदेश पंप सेट अप करने के लिए चलाएं।

मुझे लगता है कि एक बार संदेश पंप का अंतिम रूप बंद हो जाता है - यह स्वयं को समाप्त कर देगा और अंत करेगा।

ध्यान दें कि ये सभी सहायक आप एक अलग यूआई थ्रेड में विंडो खोलना चाहते हैं ... अन्यथा आपको सृजन के लिए मुख्य यूआई थ्रेड पर वापस जाने की आवश्यकता है और खिड़की के सभी हेरफेर, इसलिए यह संलग्न हो जाता है मौजूदा संदेश पंप। दोनों के लिए अच्छे मामले हैं - कोई थिंक को सरल रखता है, दूसरा बहुत अधिक प्रदर्शन की अनुमति देता है क्योंकि प्रत्येक विंडो में एक अलग संदेश पंप होता है और इस प्रकार व्यक्तिगत रूप से कार्य कर सकता है - उदाहरण के लिए यह उन व्यापारिक अनुप्रयोगों में बहुत अधिक उपयोग किया जाता है जिन्हें ग्राफ को अपडेट करने की आवश्यकता हो सकती है UI में एकल थ्रेड किए जाने पर कई स्क्रीन और हैसा बाधाएं।

ThreadCreateCurvedGraph() के बाद बाहर निकलता है, myGraph गुंजाइश और बंद से बाहर चला जाता है:

-1

शायद यह कचरा संग्रहण है।

आपको उदाहरण के लिए थ्रेड का एक तरीका व्यवस्थित करने की आवश्यकता है और इसे बंद करने के लिए प्रतीक्षा करें (अवरुद्ध प्रतीक्षा का उपयोग करके)।

संपादित करें: उदाहरण के लिए जोड़ें:

Application.Run(myGraph) 

विधि के अंत तक।
(टॉमटॉम से टिप्पणियां देखें)

+0

नहीं, उपयोगकर्ता को नए यूआई थ्रेड के विंडोज संदेशों को संभालने के लिए एक संदेश पंप स्थापित करने की आवश्यकता है। – TomTom

+0

@ टॉमटॉम: क्या यह है: 'एप्लिकेशन.रुन (myGraph)' जो दोनों उदाहरण पर होंगे और इसे बंद करने की प्रतीक्षा करेंगे? – quamrana

+0

बिल्कुल। यह एक संदेश पंप स्थापित करेगा और उस पर आखिरी खिड़की बंद होने तक प्रतीक्षा करें। यह मुख्य धागे में जो होता है उसके समान होता है, जो शुरूआत में यूआई को थ्रेड अप नहीं करता है (यही कारण है कि आप एप्लिकेशन पढ़ते हैं। वहां रॉन)। – TomTom

-1

क्या आप इस फॉर्म को दिखाते हैं जैसे यह एक संवाद था? आप

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    myGraph.ShowDialog(); 
} 

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

+0

कोई समाधान नहीं है और गलत क्या है इसका कुल बाईपास। – TomTom

+0

ग्रेट आइडिया! मुझे लगता है कि मैं ऐसा करूंगा जैसा आपने कहा था। – menachem

+0

जहां तक ​​मुझे पता है यह काम करता है इसलिए मुझे नहीं पता कि आप मुझे नकारात्मक वोट क्यों दे रहे हैं। –

5

समस्या पोस्ट स्निपेट में नहीं है। आपको Application.Run() या Form.ShowDialog() के साथ एक नया संदेश लूप शुरू करने की आवश्यकता होगी। आपको थ्रेड गुणों का भी ख्याल रखना होगा ताकि यह यूआई थ्रेड के रूप में कार्य करने के लिए उपयुक्त हो। उदाहरण के लिए:

Thread t = new Thread(() => { 
    Application.Run(new Form2()); 
    // OR: 
    //new Form2().ShowDialog(); 
    }); 
    t.SetApartmentState(ApartmentState.STA); 
    t.IsBackground = true; 
    t.Start(); 

यहां कुछ अजीब विकल्प हैं। फ़ॉर्म को आपके मुख्य धागे पर किसी भी रूप से स्वामित्व नहीं किया जा सकता है, जो आमतौर पर जेड-ऑर्डर समस्याओं का कारण बनता है। यूआई थ्रेड का मुख्य रूप बंद होने पर आपको कुछ सार्थक करने की भी आवश्यकता होगी। IsBackground का उपयोग करके यहां हल किया गया।

विंडोज़ को एक थ्रेड पर चलने वाली कई विंडो का समर्थन करने के लिए डिज़ाइन किया गया था। अगर आप वास्तव में को हैं तो केवल इस तरह के कोड का उपयोग करें। आपको कभी नहीं होना चाहिए ...

+0

अंतिम भाग को छोड़कर महान - आपको कभी भी नहीं करना चाहिए। कभी एक व्यापारिक अनुप्रयोग देखा गया है ... यूआई 6 स्क्रीन पर यूआई गिरने के इतने सारे अपडेट करता है;) एक ज़रूरत है। – TomTom

+0

@ टॉमटॉम: मुझे नहीं पता कि यहां शोडियलॉग डालने में गलत क्यों नहीं है जैसा मैंने बताया था। –

0

आप एक नए धागे पर एक फॉर्म क्यों बना रहे हैं? कई बार आपको एक नए थ्रेड का उपयोग करने की आवश्यकता होती है लेकिन दूसरी बार आप मुख्य थ्रेड पर फॉर्म .ShDDialog() का उपयोग कर सकते हैं।

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