हमारे पास एक लाइब्रेरी है जिसका उपयोग WPF और/या Winforms क्लाइंट द्वारा किया जा रहा है।एसिंक पर डेडलॉक से परहेज करें और यूआई को उत्तरदायी होने से रोकें
int GetInt();
जो अनिवार्य रूप से बस अतुल्यकालिक विधि और कॉल कॉल:
Task<int> GetIntAsync()
हम यह भी (दुर्भाग्य से) एक तुल्यकालिक आवरण विधि प्रदान की है:
हम एक अतुल्यकालिक विधि के समान प्रदान की है अपने काम पर .Result
।
हमने हाल ही में कुछ परिस्थितियों में महसूस किया है GetIntAsync
में कुछ कोड मुख्य यूआई थ्रेड पर चलाने की जरूरत है (इसे एक विरासत COM घटक का उपयोग करने की आवश्यकता है जिसे "एकल" थ्रेडिंग मॉडल के रूप में चिह्नित किया गया है (यानी घटक मुख्य में चलाना चाहिए एसटीए धागा नहीं बस किसी भी एसटीए धागा)
तो समस्या यह है कि GetInt()
, यह होगा गतिरोध
.Result
ब्लॉक मुख्य थ्रेड, मुख्य थ्रेड पर कहा जाता है जबGetIntAsync()
के भीतर कोड मुख्य धागे पर चलाने के प्रयास के लिएDispatcher.Invoke
का उपयोग करता है।
सिंक्रोनस विधि पहले से ही उपभोग की जा रही है, इसलिए इसे हटाने के लिए यह एक तोड़ने वाला परिवर्तन होगा। तो इसके बजाय, हमने मुख्य सिग्नल पर काम करने की अनुमति देने के लिए हमारे सिंक्रोनस GetInt()
विधि में WaitWithPumping का उपयोग करने का विकल्प चुना है।
यह उन यूआई कोडों से GetInt()
का उपयोग करने वाले ग्राहकों को छोड़कर ठीक काम करता है। पहले, उन्होंने उम्मीद की थी कि GetInt()
का उपयोग करके उनके यूआई को उत्तरदायी छोड़ दिया जाएगा - यानी, यदि वे बटन के क्लिक इवेंट हैंडलर से GetInt()
कहलाते हैं, तो वे उम्मीद करेंगे कि हैंडलर लौटने तक कोई विंडोज संदेश संसाधित नहीं किया गया था। अब उन संदेशों को पंप किया गया है, उनके यूआई उत्तरदायी हैं और उसी बटन को फिर से क्लिक किया जा सकता है (और संभवतः वे अपने हैंडलर को पुन: प्रवेश करने के लिए कोड नहीं देते थे)।
- क्या कोई:
अगर वहाँ एक उचित समाधान है, हम अपने ग्राहकों के लिए नहीं करना चाहते हैं
GetInt
प्रश्न कॉल के दौरान उत्तरदायी होने यूआई के खिलाफ कोड करने के लिए की जरूरत है
WaitWithPumping
करने का तरीका जो "मुख्य पर आमंत्रित करें" संदेशों को पंप करेगा, लेकिन अन्य UI संबंधित संदेशों को पंप नहीं करेगा? - यह हमारे उद्देश्यों के लिए पर्याप्त होगा यदि क्लाइंट यूआई व्यवहार करता है जैसे कि एक मॉडल संवाद वर्तमान में दिखाया गया था, हालांकि छुपा हुआ है (यानी उपयोगकर्ता अन्य विंडो तक नहीं पहुंच सका)। लेकिन, जो मैंने पढ़ा है, उससे आप एक मोडल संवाद छुपा नहीं सकते हैं।
- अन्य कामकाज जिनके बारे में आप सोच सकते हैं उनकी सराहना की जाएगी।
धन्यवाद। मुझे यूआई ब्लॉक दिखाई देता है। असुरक्षित रूप से मुख्य धागे तक पहुंचने का प्रयास मुख्य थ्रेड के लिए मुख्य थ्रेड के डिस्पैचर 'डिस्पैचर। इन्वोक' का उपयोग कर रहा है। मैं इस काम को बनाने का अनुमान लगा रहा हूं, मुझे मुख्य थ्रेड के डिस्पैचर की बजाय सिंक्रनाइज़ेशन कॉन्टेक्स्ट का उपयोग करने के लिए उस कोड को बदलने की आवश्यकता होगी। क्या यह मुख्य धागे के डिस्पैचर के साथ काम करने का कोई तरीका है? –
@MattSmith आपका कोड विशेष रूप से काम नहीं कर रहा है क्योंकि आप मुख्य थ्रेड के प्रेषक का उपयोग कर रहे हैं। – Servy