कई जीयूआई धागे "स्पिन ऑफ" संभव है? (एप्लिकेशन पर सिस्टम को रोक नहीं रहा। रुन)

मेरा लक्ष्य

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

पृष्ठभूमि

मेरे पास एक घटक आधारित सिस्टम है जिसमें एक नियंत्रक गतिशील रूप से असेंबली लोड करता है और एक सामान्य IComponent इंटरफ़ेस को एक विधि DoStuff() के साथ कार्यान्वित करने वाले वर्ग चलाता है।

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

पूरी प्रणाली का जीवनकाल इस तरह दिखता है

  1. एप्लिकेशन शुरू होता है।
  2. लोड करने के लिए घटकों के लिए कॉन्फ़िगरेशन फ़ाइल जांचें। उन्हें लोड करें।
  3. प्रत्येक घटक के लिए, इसे प्रारंभ करने के लिए DoStuff() चलाएं और इसे अपने स्वयं के धागे में अपना जीवन बना दें।
  4. काम के मुख्य आवेदन-काम करने वाले राजा को हमेशा के लिए जारी रखना जारी रखें।

यदि घटक DoStuff() में एक GUI को सक्रिय करता है तो मैं अभी तक सफलतापूर्वक बिंदु 3 निष्पादित करने में सक्षम नहीं हूं। यह बस तब तक रुक जाता है जब तक कि जीयूआई बंद नहीं हो जाता है। और जब तक जीयूआई बंद नहीं हो जाता है, तब तक प्रोग्राम 4 बिंदु पर प्रगति करता है।

यह अच्छा होगा अगर इन घटकों को अपने स्वयं के विंडोज फॉर्म जीयूआई शुरू करने की अनुमति दी गई।

समस्या

जब कोई घटक DoStuff() में एक GUI को आग लगाने का प्रयास करता है (कोड की सटीक पंक्ति तब होती है जब घटक Application.Run (theorm) चलाता है), घटक और इसलिए जीयूआई बंद होने तक हमारी प्रणाली "कोड> एप्लिकेशन.रुन() लाइन पर" लटकती है "। खैर, बस निकाल दिया गया जीयूआई ठीक काम करता है, जैसा कि अपेक्षित है।

घटकों का उदाहरण किसी के पास जीयूआई के साथ कुछ लेना देना नहीं है, जबकि दूसरे में एक प्यारी खिड़कियां आग लगती हैं जिसमें गुलाबी फफूंदी बनी होती है।

public class MyComponent1: IComponent
{
    public string DoStuff(...) { // write something to the database  }
}

public class MyComponent2: IComponent
{
    public void DoStuff()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form());

        // I want the thread to immediately return after the GUI 
        // is fired up, so that my main thread can continue to work.
    }
}

मैंने भाग्य के साथ यह कोशिश की है। यहां तक ​​कि जब मैं अपने स्वयं के धागे में जीयूआई को आग लगाने की कोशिश करता हूं, तब भी निष्पादन बंद होने तक जीयूआई बंद हो जाता है।

public void DoStuff()
{
    new Thread(ThreadedInitialize).Start()
}

private void ThreadedInitialize()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form());
}

क्या एक GUI को स्पिन करना और Application.Run() के बाद वापस जाना संभव है?

0
जोड़ा संपादित
विचारों: 4

3 उत्तर

मुझे यकीन है कि यह संभव है यदि आप इसे पर्याप्त रूप से हैक करते हैं, लेकिन मैं सुझाव दूंगा कि यह एक अच्छा विचार नहीं है।

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

इस वजह से, यह कम या ज्यादा माना जाता है कि यदि आपके पास कोई संदेश लूप है, तो यह आपकी प्रक्रिया के जीवनकाल के लिए उपलब्ध होना चाहिए। उदाहरण के लिए विंडोज़ आपको 'छोड़ने' संदेश भेज सकती हैं, और आपको इसे संभालने के लिए एक संदेश लूप उपलब्ध होना चाहिए, भले ही आपके पास स्क्रीन पर कुछ भी न हो।

आपकी सबसे अच्छी शर्त इस तरह है:

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

0
जोड़ा
दरअसल, खिड़कियां धागे के साथ मिलती हैं, न कि प्रक्रियाओं। आपके पास प्रति प्रक्रिया एकाधिक संदेश लूप हो सकते हैं और यह आपको कई पूरी तरह से स्वतंत्र विंडोज़ देगा।
जोड़ा लेखक Garo Yeriazarian, स्रोत

Application.Run method displays one (or more) forms and initiates the standard message loop which runs until all the forms are closed. You cannot force a return from that method except by closing all your forms or forcing an application shutdown.

You can, however, pass an ApplicationContext (instad of a new Form()) to Application.Run method and ApplicationContext can be used to launch several forms at once. Your application will only end when all of those are closed. See here: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx

साथ ही, जो भी रूप आप गैर-मोडल दिखाते हैं, वह आपके मुख्य रूप के साथ चलना जारी रखेगा, जिससे आप एक से अधिक खिड़कियां प्राप्त कर सकेंगे जो एक दूसरे को अवरुद्ध नहीं करते हैं। मेरा मानना ​​है कि यह वास्तव में आप जो करने की कोशिश कर रहे हैं वह वास्तव में है।

0
जोड़ा

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

बेशक घटक इसके रूपों के संदर्भ को बनाए रखने के लिए जिम्मेदार होगा

0
जोड़ा