C # 5 के लिए समाधान फिर से प्रवेश करें


16

तो, कुछ मुझे C # 5 में नए async समर्थन के बारे में बता रहा है:

उपयोगकर्ता एक बटन दबाता है जो एक async ऑपरेशन शुरू करता है। कॉल तुरंत वापस आ जाता है और संदेश पंप फिर से चलने लगता है - यही पूरा बिंदु है।

तो उपयोगकर्ता फिर से बटन दबा सकता है - फिर से प्रवेश कर सकता है। क्या होगा अगर यह एक समस्या है?

जिन डेमो में मैंने देखा है, वे awaitकॉल से पहले बटन को अक्षम करते हैं और बाद में फिर से सक्षम करते हैं। यह मुझे एक वास्तविक दुनिया में एक बहुत ही नाजुक समाधान की तरह लगता है।

क्या हमें किसी प्रकार की राज्य मशीन को कोडित करना चाहिए जो निर्दिष्ट संचालन के दिए गए सेट के लिए कौन से नियंत्रण को अक्षम करना चाहिए? या कोई बेहतर तरीका है?

मुझे ऑपरेशन की अवधि के लिए सिर्फ एक मामूली संवाद दिखाने के लिए लुभाया जाता है, लेकिन यह एक स्लेजहैमर का उपयोग करने जैसा लगता है।

किसी को कोई उज्ज्वल विचार मिला, कृपया?


संपादित करें:

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

क्या होगा अगर नियंत्रण का एक संग्रह है जिसे किसी विशेष ऑपरेशन के लिए अक्षम किया जाना चाहिए? और क्या होगा अगर कई ऑपरेशन समवर्ती चल रहे हैं?


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

PS: क्या .NET 4.5 के C # को C # 5 कहा जाता है?
स्टीवन ज्यूरिस

1
बस उत्सुक क्यों यह सवाल यहाँ है और एसओ नहीं है? यह निश्चित रूप से कोड के बारे में है इसलिए यह वहां होगा जो मुझे लगता है ...
सी। रॉस

@ C.Ross, यह एक डिज़ाइन / UI प्रश्न से अधिक है। वास्तव में एक तकनीकी बिंदु नहीं है जिसे यहां समझाया जाना चाहिए।
बजे मॉर्गन हेरलॉकर

हमें ajax HTML फॉर्म में एक समान समस्या है जहाँ एक उपयोगकर्ता सबमिट बटन दबाता है, एक अजाक्स अनुरोध भेजा जाता है और हम उपयोगकर्ता को फिर से सबमिट करने से रोकना चाहते हैं, बटन को निष्क्रिय करना उस स्थिति में एक बहुत ही सामान्य समाधान है
Raynos

जवाबों:


14

इसलिए, कुछ मुझे C # 5 में नए async समर्थन के बारे में परेशान कर रहा है: उपयोगकर्ता एक बटन दबाता है जो एक async ऑपरेशन शुरू करता है। कॉल तुरंत वापस आ जाता है और संदेश पंप फिर से चलने लगता है - यही पूरा बिंदु है। तो उपयोगकर्ता फिर से बटन दबा सकता है - फिर से प्रवेश कर सकता है। क्या होगा अगर यह एक समस्या है?

आइए यह देखते हुए शुरू करें कि यह पहले से ही एक समस्या है, यहां तक ​​कि भाषा में async समर्थन के बिना भी। जब आप किसी ईवेंट को हैंडल कर रहे हों, तो बहुत सी चीजें संदेशों को नष्ट कर सकती हैं। आपको पहले से ही इस स्थिति के लिए रक्षात्मक रूप से कोड करना होगा; नई भाषा की सुविधा सिर्फ इतना स्पष्ट करती है , जो अच्छाई है।

अनचाहे पुन: प्रवेश के कारण किसी घटना के दौरान चलने वाले संदेश लूप का सबसे आम स्रोत है DoEventsawaitविरोध के रूप में अच्छी बात यह DoEventsहै कि awaitयह अधिक संभावना है कि नए कार्य वर्तमान में चल रहे कार्यों को "भूखा" नहीं जा रहे हैं। DoEventsसंदेश पाश पंप और फिर तुल्यकालिक फिर से प्रवेशी ईवेंट हैंडलर का आह्वान है, जबकि awaitआम तौर पर enqueues इतना है कि यह भविष्य में कुछ बिंदु पर चलेंगे नया कार्य।

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

आप उस जटिलता को उसी तरह से प्रबंधित कर सकते हैं जिस तरह से आप OO भाषा में किसी अन्य जटिलता का प्रबंधन करेंगे: आप तंत्र को एक वर्ग में दूर करते हैं, और एक नीति को सही ढंग से लागू करने के लिए वर्ग को जिम्मेदार बनाते हैं । (तंत्र को नीति से तार्किक रूप से अलग रखने का प्रयास करें; यह तंत्र के साथ अतिव्याप्ति के बिना नीति को बदलना संभव होना चाहिए।)

यदि आपके पास इस पर बहुत सारे नियंत्रण हैं जो दिलचस्प तरीकों से बातचीत करते हैं तो आप अपनी खुद की बनाने की जटिलता की दुनिया में रह रहे हैं । आपको उस जटिलता को प्रबंधित करने के लिए कोड लिखना है; अगर आपको यह पसंद नहीं है तो फॉर्म को सरल बनाएं ताकि यह इतना जटिल न हो।

मुझे ऑपरेशन की अवधि के लिए सिर्फ एक मामूली संवाद दिखाने के लिए लुभाया जाता है, लेकिन यह एक स्लेजहैमर का उपयोग करने जैसा लगता है।

यूजर्स इससे नफरत करेंगे।


धन्यवाद एरिक, मुझे लगता है कि यह निश्चित उत्तर है - यह एप्लिकेशन डेवलपर पर निर्भर है।
निकोलस बटलर

6

आपको ऐसा क्यों लगता है कि बटन को निष्क्रिय करने से पहले awaitऔर फिर कॉल सक्षम होने पर इसे फिर से सक्षम करें? क्या यह इसलिए है क्योंकि आप चिंतित हैं कि बटन फिर से सक्षम नहीं होगा?

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

केवल यही समय गड़बड़ हो सकता है यदि कई ऑपरेशन हैं जो एक बटन की स्थिति को प्रभावित करते हैं, लेकिन मुझे लगता है कि उन स्थितियों को बहुत दुर्लभ होना चाहिए।


बेशक आपको त्रुटियों को संभालना है - मैंने अपना प्रश्न अपडेट किया है
निकोलस बटलर

5

मुझे यकीन नहीं है कि यह आपके लिए लागू होता है क्योंकि मैं आमतौर पर WPF का उपयोग करता हूं, लेकिन मुझे लगता है कि आप ViewModelइसे संदर्भित कर रहे हैं।

बटन को अक्षम करने के बजाय, एक IsLoadingध्वज सेट करें true। फिर जिस भी यूआई तत्व को आप निष्क्रिय करना चाहते हैं, वह ध्वज से बंधा हो सकता है। अंतिम परिणाम यह है कि यह यूआई का काम बन जाता है ताकि यह पता चल सके कि यह स्वयं सक्षम राज्य है, न कि आपका व्यावसायिक तर्क।

इसके अलावा, WPF में अधिकांश बटन एक के लिए बाध्य होते हैं ICommand, और आमतौर पर मैं इसके ICommand.CanExecuteबराबर सेट करता हूं !IsLoading, इसलिए यह स्वचालित रूप से कमांड को निष्पादित करने से रोकता है जब IsLading सच के बराबर होता है (मेरे लिए बटन को निष्क्रिय भी करता है)


3

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

इस बारे में कुछ भी नाजुक नहीं है, और यह वही है जो उपयोगकर्ता अपेक्षा करेगा। यदि उपयोगकर्ता को बटन को फिर से मारने से पहले प्रतीक्षा करने की आवश्यकता है तो उन्हें प्रतीक्षा करें।

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


धन्यवाद - लेकिन जटिलता का प्रबंधन कैसे करें?
निकोलस बटलर

एक विकल्प कंटेनर में संबंधित नियंत्रण रखना होगा। नियंत्रण कंटेनर द्वारा अक्षम / सक्षम करें, नियंत्रण द्वारा नहीं। अर्थात: EditorControls.Foreach (c => c.Enabled = false);
मॉर्गन हेरलॉकर

2

विजेट को अक्षम करना कम से कम जटिल और त्रुटि-प्रवण विकल्प है। आप async कार्रवाई शुरू करने से पहले इसे हैंडलर में अक्षम कर देते हैं और आप इसे ऑपरेशन के अंत में पुनः सक्षम करते हैं। तो प्रत्येक नियंत्रण के लिए अक्षम + सक्षम उस नियंत्रण को संभालने के लिए स्थानीय रखा जाता है।

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

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

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


धन्यवाद - मुझे यह विचार पसंद आया। तो क्या आपके पास अपनी खिड़की के लिए एक प्रबंधक वस्तु होगी जो प्रत्येक नियंत्रण के लिए अक्षम और सक्षम अनुरोधों की संख्या को गिनाती है?
निकोलस बटलर

@NickButler: ठीक है, आपके पास प्रत्येक विंडो के लिए पहले से ही एक प्रबंधक ऑब्जेक्ट है- फ़ॉर्म। इसलिए मेरे पास अनुरोधों और गिनती को लागू करने वाला एक वर्ग होगा और केवल प्रासंगिक रूपों के उदाहरणों को जोड़ना होगा।
जन हडेक

1

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.