2009-11-13 20 views
18

एसिंक्रोनस कॉल को कैसे रद्द करें? .NET एपीएम इस ऑपरेशन का समर्थन नहीं कर रहा है।एसिंक्रोनस कॉल को कैसे रद्द करें?

मेरे पास मेरे कोड में निम्न लूप है जो थ्रेडपूल पर एकाधिक धागे उत्पन्न करता है। जब मैं अपने यूआई पर एक बटन क्लिक करता हूं, तो मुझे ये थ्रेड (या असीमित कॉल) समाप्त करना होगा।

foreach (var sku in skus) 
{ 
    loadSku.BeginInvoke(... 
} 

क्या ग्लोबल "फ्लैग रद्द करें" बनाने के अलावा कोई अजीब समाधान है और इसे देखने के लिए असीमित तरीके हैं?

उत्तर

18

ए "फ्लैग रद्द करें" ऐसा करने का तरीका है, हालांकि वैश्विक नहीं, जरूरी है। अपरिहार्य बिंदु यह है कि आपको कुछ थ्रेड को सिग्नल करने के तरीके की आवश्यकता है कि इसे जो करना है उसे रोकना चाहिए।

BeginInvoke के मामले में, वैश्विक ध्वज के अलावा कुछ भी करना मुश्किल है, क्योंकि काम थ्रेडपूल पर किया जाता है, और आप नहीं जानते कि कौन सा धागा है। आप (वरीयता के क्रम में) पास कुछ विकल्प होते हैं:

  1. BeginInvoke के बजाय BackgroundWorker का प्रयोग करें। इसमें cancellation functionality baked-in है। इसमें अन्य लाभ हैं, जैसे progress monitoring, और "Work complete" callbacks। यह अच्छी तरह से handles exceptions है।
  2. ThreadPool.QueueUserWorkItem का उपयोग करें, किसी ऑब्जेक्ट में Cancel() विधि है जो Cancelled ध्वज सेट करता है जो निष्पादन कोड जांच सकता है। बेशक आपको राज्य ऑब्जेक्ट का संदर्भ रखना होगा ताकि आप Cancel() पर कॉल कर सकें (जो BackgroundWorker आपके लिए कुछ करता है - आपके पास आपके फॉर्म पर एक घटक है। (Fredrik को इसके बारे में याद दिलाने के लिए धन्यवाद)
  3. अपनी खुद की ThreadStart प्रतिनिधि बनाएं, विकल्प के साथ के रूप में एक राज्य वस्तु में गुजर 2.
+0

+1 - एक अतिरिक्त के रूप में; 'ThreadPool.QueueUserWorkItem' के साथ उपयोग किया गया 'WaitCallback' एक कस्टम ऑब्जेक्ट पैरामीटर लेता है, ताकि कस्टम थ्रेडस्टार्ट प्रतिनिधियों को बनाने के बजाय भी इसका उपयोग किया जा सके। –

+0

आह हाँ - मैं आपके QueueUserWorkItem बिंदु को plagarise करेंगे। यह काफी हद तक वही है, लेकिन मुझे खुद को धागे के प्रबंधन के बजाय ** ** हमेशा टीपी.QUWI का उपयोग करना है। –

+0

+1: और QUWI के विषय पर, यह अधिक हल्का वजन है क्योंकि पूल पूर्ण नहीं होने पर थ्रेड बनाने की आवश्यकता नहीं है (/ हो सकता है)। –

1

यदि आप "TerminateAsnyc" विधि के लिए देख रहे हैं, तो आपको एक नहीं मिलेगा। इसलिए, नहीं, Control.BeginInvoke/EndInvoke का उपयोग करते समय शायद कोई सुरुचिपूर्ण तरीका नहीं है। इस प्रकार, मैं यूआई थ्रेड पर बूलियन ध्वज डालूंगा और प्रतिनिधि को निष्पादित होने पर समय-समय पर ध्वज को अनियंत्रित रूप से निष्पादित किया जा रहा है।

हालांकि, आप पृष्ठभूमि कार्यकर्ता धागे का उपयोग कर जांच सकते हैं।

0

वहाँ निश्चित रूप से अन्य समाधान कर रहे हैं, हालांकि मुझे नहीं पता है कि मैं उन्हें "सुरुचिपूर्ण" कहेंगे।

आप थ्रेड पर गर्भपात या इंटरप्ट को कॉल कर सकता है लेकिन इनके कुछ नकारात्मक दुष्प्रभाव हो सकते हैं। व्यक्तिगत रूप से, इस तरह के कुछ के लिए मैं prefe यदि संभव हो तो BackgroundWorker का उपयोग करने के लिए आर। इसमें एक रद्द सुविधा है लेकिन यह आपके जैसा उल्लेख है - कक्षा में एक बूल ध्वज जिसे आपको समय-समय पर निष्पादन कोड में जांचना है (कम से कम यह वैश्विक ध्वज नहीं है)। This post on stopping threads in .NET थोड़ा पुराना है लेकिन ऊपर वर्णित अन्य विकल्पों के कुछ नुकसानों पर चला जाता है।

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