2009-03-15 15 views
10

मुझे एक Winforms एप्लिकेशन विरासत में मिला है जो यूआई थ्रेड से एप्लिकेशन सर्वर में बहुत अधिक लंबी कॉल करता है, इसलिए UI कुछ समय के लिए उत्तरदायी, अनुपयोगी, अव्यवस्थित रहता है । (बनाता कौन सा मुझे वास्तव में जाना AAAAAAAAARGH!)पृष्ठभूमि थ्रेड चल रहा है, जबकि Winforms UI को अवरुद्ध करने के लिए कैसे करें

मैं सर्वर एक पृष्ठभूमि धागा करने के लिए कॉल स्थानांतरित करने के लिए योजना बनाने और यूआई अक्षम है - लेकिन चल & closable - समय पृष्ठभूमि धागा अपने काम करता है।

तो मेरे आवेदन में उपयोगकर्ता इनपुट को बाधित करने का सबसे अच्छा तरीका क्या होगा? मैं "मोडल प्रोग्रेस डायलॉग" की लाइनों के साथ सोच रहा हूं, लेकिन मैं एक ऐसा समाधान पसंद करूंगा जो मुझे उपयोगकर्ता के चेहरे में दृश्यों को फेंकने के लिए मजबूर नहीं करता है (कुछ सर्वर ऑपरेशंस 500ms से कम के भीतर चलते हैं, इसलिए एक संवाद नहीं है इष्टतम ...)

क्या Winforms में उपयोगकर्ता को कुछ चुनिंदा चीजों (आकार बदलने, दिखाने, छिपाने और परिवार और खिड़की को बंद करने वाले उपयोगकर्ता के माध्यम से एप्लिकेशन को क्रियाएं लॉन्च करने या एप्लिकेशन में डेटा बदलने से रोकने का कोई तरीका है))? मैं एक ऐसा तरीका पसंद करूंगा जो मुझे मेरे फॉर्म में प्रत्येक यूआई तत्व को एक्सेस न करे और इसे अक्षम कर दें ... उनमें से बहुत सारे हैं और उस एप्लिकेशन में वास्तव में "यूआई डिज़ाइनर में हैक किया गया है जब तक यह चमकदार चीजें नहीं दिखाता "स्रोत कोड की शैली। रिलीज की तारीख तक हर बदबूदार बात पुनर्रचना का कोई रास्ता नहीं ...

ओह, वैसे, इस एप्लिकेशन .नेट फ्रेमवर्क में रहती है 2

+0

आप लंबे समय तक चलने वाले कॉल को शुरू करने वाले बटन को अक्षम क्यों नहीं करते? –

+0

यूआई एक डेटा एंट्री फॉर्म है, लंबी चल रही कॉल एक "सेव" हो सकती है जिसमें कई डोमेन ऑब्जेक्ट शामिल हैं। उदाहरण के लिए सहेजते समय मैं उपयोगकर्ता को फ़ॉर्म में किसी भी डेटा को बदलने से रोकना चाहता हूं। वैसे (http://stuffthathappens.com/blog/2008/03/05/simplicity) बहुत सच है ... – froh42

+0

जब आप फॉर्म को वापस सक्षम करना चाहते हैं? यदि आप इसे "_RunWorkerCompleted" ईवेंट पर करने का प्रयास करते हैं तो आपको अपवाद मिलेगा क्योंकि आपको अनुमति नहीं है (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx - पहला नोट)। आप फॉर्म में या पहले कंटेनर के लिए प्रत्येक आइटम के लिए इसे मैन्युअल रूप से कर सकते हैं। – Edd

उत्तर

6

एक ही रास्ता मैं जानता हूँ कि के कुछ/विकलांग के रूप में सभी नियंत्रण प्राप्त करने के लिए है । हालांकि, नियंत्रण कैसे निर्धारित किए जाते हैं, इस पर निर्भर करता है कि प्रत्येक नियंत्रण को अक्षम के रूप में सेट करना आवश्यक नहीं है - जब एक कंटेनर नियंत्रण अक्षम होता है, तो उसके सभी बच्चे अक्षम भी होते हैं। उदाहरण के लिए, यदि आपके पास GroupBox कुछ नियंत्रणों के साथ है, तो यदि आप GroupBox अक्षम करने के लिए सेट करते हैं, तो GroupBox के भीतर सभी नियंत्रण अक्षम भी होंगे।

+0

संभव नहीं है: क्रॉस-थ्रेड ऑपरेशन मान्य नहीं है: इसे बनाए गए थ्रेड के अलावा किसी थ्रेड से 'समूहबॉक्स 2' को नियंत्रित किया गया था। :( – Edd

+1

@Edd आपको यूआई थ्रेड से UI को अक्षम करने की आवश्यकता होगी, पृष्ठभूमि थ्रेड नहीं। फिर यह काम करेगा। – Andy

+0

आप सही हैं, लेकिन पृष्ठभूमि कार्यकर्ता में प्रक्रिया पूरी होने पर आप इसे कैसे सक्षम करते हैं? क्या आप यूआई फॉर्म को सक्षम करने के लिए संकेत देते हैं? क्योंकि पूर्ण घटना से, आप नहीं कर सकते हैं। – Edd

5

कुछ ऊपरी स्तर के कंटेनर नियंत्रण (स्वयं ही फॉर्म हो सकता है) चुनें, और इसे सक्षम संपत्ति को गलत पर सेट करें। उस नियंत्रण पर रखे गए सभी नियंत्रण अक्षम हो जाएंगे, जो उन्हें इनपुट प्राप्त करने से रोक देंगे।

0

दुर्भाग्य से, WinForms के साथ, आपको शायद एक साझा साझा विधि में बटन को अक्षम/सक्षम करने की आवश्यकता होगी। यह डब्ल्यूपीएफ विंडोज़ फॉर्मों पर लाए जाने वाले फायदों में से एक है - इन परिस्थितियों को संभालना बहुत आसान है।

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

आप बटन को अपने नियंत्रण अक्षम करने जैसे कुछ करना चाहते हैं, थ्रेड पूल पर अपना ऑपरेशन कॉल करें, फिर उन्हें पूरा होने पर पुन: सक्षम करें।

1

Win32 API स्तर पर, EnableWindow फ़ंक्शन है जिसमें आप किसी भी विंडो हैंड को अक्षम कर सकते हैं (आपको अपनी मुख्य विंडो, निश्चित रूप से और किसी अन्य शीर्ष स्तर की विंडो के अंतर्निहित हैंडल को प्राप्त करने की आवश्यकता है)। मैंने WinForms में इसका परीक्षण नहीं किया है, हालांकि। (मुझे यकीन है कि उपयोगकर्ता 32 स्तर पर अन्य उत्तर हैं, लेकिन मुझे अभी एपीआई कॉल याद नहीं आ रहे हैं।)

नोट: यह ग्रे आउट नियंत्रण नहीं करता है, जो उपयोगिता बिंदु से इसकी उपयोगिता को कम करता है देखने के लिए (उपयोगकर्ता सिर्फ 'जमे हुए आवेदन' देखता है)। यदि आप कम से कम एक घंटे का चश्मा कर्सर सेट करते हैं तो यह थोड़ा बेहतर हो जाता है।

हालांकि, यह एसिंक्रोनस प्रोसेसिंग से निपटने का एक त्वरित और गंदा तरीका है। क्या आपको वास्तव में उपयोगकर्ता को अपने पूरे एप्लिकेशन से लॉक करने की आवश्यकता है?शायद यह केवल कुछ कार्य हैं जिन्हें अनुरोध जारी होने पर प्रतिबंधित किया जाना चाहिए?

3

बस को सक्षम/अक्षम करने बटन के साथ समस्या यह है कि यूआई घटनाओं अभी भी messagequeue में जोड़ दी जाती है, जबकि कार्य चल रहा है है ....

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

इस के आसपास त्वरित और गंदी तरह से ठीक पहले को पुन: सक्षम बटन एक

Application.DoEvents(); 

कॉल जोड़ना है। DoEvents() नियंत्रण पर सभी क्लिक ईवेंट को संसाधित करेगा, जिसे अभी भी अक्षम किए गए नियंत्रणों के लिए अनदेखा कर दिया जाएगा।

+0

ओह, यह * भयानक * है। मैं इसका उपयोग कर रहा हूं। चीयर्स। – Frosty840

0

मैं यहां एक पुराने धागे का जवाब दे रहा हूं, लेकिन मैंने यह प्रश्न देखा और मेरा एक पुराना WinForm ऐप याद किया जहां मुझे एक फॉर्म को अक्षम करने की एक ही समस्या थी, जबकि इसे अभी भी आकार बदलने और स्थानांतरित करने की इजाजत थी। मैं लोड हो गया मेरा कोड और पाया गया कि समाधान था:

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

कड़ाई से बोलते हुए, आपको पैनल नियंत्रण का उपयोग करने की आवश्यकता नहीं है, किसी भी कंटेनर नियंत्रण को एक ही व्यवहार प्रदर्शित करना चाहिए। यहां तक ​​कि एक पिक्चरबॉक्स नियंत्रण भी चाल करेगा!

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