2008-11-03 11 views
72

में अनचाहे अपवाद, मेरे WinForms ऐप डेटाबेस से जानकारी पुनर्प्राप्त करने के लिए BackgroundWorker ऑब्जेक्ट्स का उपयोग करता है। मैं BackgroundWorker का उपयोग कर रहा हूं क्योंकि यह यूआई को लंबे समय से चलने वाले डेटाबेस प्रश्नों के दौरान अनब्लॉक करने की अनुमति देता है और यह मेरे लिए थ्रेडिंग मॉडल को सरल बनाता है।पृष्ठभूमिवर्कर

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

मेरा प्रश्न यह है कि क्या होता है जब इन पृष्ठभूमि कार्यकर्ता धागे में से एक में एक अनचाहे अपवाद होता है।

मुझे नहीं लगता कि मैं किसी अन्य धागे में अपवाद पकड़ सकता हूं, लेकिन क्या मैं अपने वर्कर पूर्ण विधि को निष्पादित करने की अपेक्षा कर सकता हूं? क्या पृष्ठभूमिवर्कर की कोई संपत्ति या विधि अपवादों के लिए पूछताछ कर सकती है?

उत्तर

77

तो आपरेशन एक अपवाद है कि आपके कोड को संभाल नहीं करता है को जन्म देती है, BackgroundWorker अपवाद पकड़ता और RunWorkerCompleted ईवेंट हैंडलर, जहां यह System.ComponentModel.RunWorkerCompletedEventArgs की त्रुटि संपत्ति के रूप में सामने आ रहा है में से गुजरता है। यदि आप विजुअल स्टूडियो डीबगर के तहत चल रहे हैं, तो डीबगर डॉकवर्क इवेंट हैंडलर के बिंदु पर तोड़ देगा जहां अनचाहे अपवाद उठाया गया था।

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.dowork.aspx

+5

यह ऐसा करेगा। बेशक, आप हमेशा अपने DoWork विधि में अपवाद पकड़ सकते हैं, और तदनुसार प्रतिक्रिया दे सकते हैं (यदि आप UI को अपडेट करने जा रहे हैं तो Control.Invoke का उपयोग करना याद रखें)। लेकिन RunWorker पूर्ण वास्तव में सरल है। –

+0

मुझे यह समाधान मिल रहा है। मेरा रनवर्कर पूर्ण नहीं होता है जब मैं बस नई अपवाद() को फेंक देता हूं लेकिन अनचाहे अपवाद उठाया जाता है। DoWork में पकड़ असली जवाब नहीं है। मेरे BackgroundWorker में कुछ गलत होना चाहिए। – CallMeLaNN

+0

मैंने पिछले सात घंटों में यह पता लगाने की कोशिश की है कि मेरा ऐप क्यों नहीं चलेगा और बस बाहर निकल जाएगा, और सब कुछ क्योंकि पृष्ठभूमिवर्कर में एक त्रुटि हुई है जिसे सही तरीके से पकड़ा नहीं जा रहा था। आपको +1 और मुझे लगता है कि आप एक बियर के लायक भी हैं :-) – EvilDr

10

डिफ़ॉल्ट रूप से यह पकड़ लिया और BackgroundWorker द्वारा संग्रहीत किया जाएगा। MSDN से:

तो आपरेशन एक अपवाद है कि आपके कोड को संभाल नहीं करता है को जन्म देती है, BackgroundWorker अपवाद पकड़ता और RunWorkerCompleted ईवेंट हैंडलर, जहां यह System.ComponentModel.RunWorkerCompletedEventArgs की त्रुटि संपत्ति के रूप में सामने आ रहा है में पास कर देता है । यदि आप विजुअल स्टूडियो डीबगर के तहत चल रहे हैं, तो डीबगर डॉकवर्क इवेंट हैंडलर के बिंदु पर तोड़ देगा जहां अनचाहे अपवाद उठाया गया था।

34

मैं पूरी तरह से BackgroundWorker का उपयोग कर रहा हूं और वास्तव में इसे गहरे में जानता हूं।

बस हाल ही में, मेरे RunWorkerCompletede.Error जब मैं बस Throw New Exception("Test")DoWork में पकड़ नहीं करता है। हालांकि अनचाहे अपवाद उठाया। DoWork में कैच करें e.Error का कोई अर्थ नहीं है।

जब मैं नए BackgroundWorker, e.ErrorRunWorkerCompleted में सफलतापूर्वक संभाला गया नया Form बनाने का प्रयास करता हूं। मेरे जटिल BackgroundWorker में कुछ गलत होना चाहिए।

कुछ दिनों के बाद googling और डिबगिंग, एक त्रुटि की कोशिश कर रहा है। के लिए e.Error पहले, तो e.Cancelled और अंत में e.Result

    • चेक मत हो e.Resulte.Cancelled = True यदि: मैं अपने RunWorkerCompleted में यह पाया।
    • मिलता है नहीं e.Result अगर e.Errornull (या Nothing) नहीं है **

    ** यह है कि मैं कहाँ याद आती है। यदि आप e.Result का उपयोग करने का प्रयास कर रहे हैं तो e.Errornull (या Nothing) नहीं है, तो अनचाहे अपवाद फेंक दिया जाएगा।


    अद्यतन: e.Result में संपत्ति नेट डिजाइन यह e.Error पहले, अगर मिल गया त्रुटि के लिए जाँच करने के लिए है, तो वे DoWork से एक ही अपवाद फिर से फेंक देते हैं मिलता है। यही कारण है कि हमें RunWorkerCompleted में अनचाहे अपवाद मिलता है लेकिन वास्तव में अपवाद DoWork से आता है।

    यहाँ RunWorkerCompleted में करने के लिए सबसे अच्छा अभ्यास है:

    Dim ThreadInfos as Dictionary(Of BackgroundWorker, YourObjectOrStruct) 
    

    आप आसानी से कर सकते हैं:

    If e.Error IsNot Nothing Then 
        ' Handle the error here 
    Else 
        If e.Cancelled Then 
        ' Tell user the process canceled here 
        Else 
        ' Tell user the process completed 
        ' and you can use e.Result only here. 
        End If 
    End If 
    

    आप एक वस्तु है कि सभी DoWork, ProgressChanged और RunWorkerCompleted के लिए सुलभ है, इस तरह उपयोग करना चाहते हैं कहीं भी ThreadInfos(sender).Field एक्सेस करें।

  • +1

    नहीं। मैंने DoWork में नई अपवाद ('टेस्ट') फेंक दिया। फिर RunWorker पूर्ण ट्रिगर किया गया और मैं e.Error से पहले e.Result को कॉल करता हूं। ये गलत है। ई.इरर की वजह से शून्य (या कुछ भी नहीं) है, हम ई। रेसल्ट को कॉल नहीं कर सकते हैं। E.Result को कॉल करना e.Error IsNot कुछ भी नहीं है या e.Cancelled = True RunWorker में एक अनचाहे अपवाद फेंक देगा। तो e.Rrult को कॉल करने से पहले e.Error और e.Cancelled की जांच करें। – CallMeLaNN

    +0

    मेरे पूर्ण ईवेंटशैंडर में ई। रीसल्ट तक पहुंचने का प्रयास करना मेरे DoWork को अनदेखा करते समय एक लक्ष्यInvocationException फेंक रहा था। अब मैं जांचता हूं कि त्रुटि शून्य है या परिणाम पहुंचने से पहले इसे रद्द कर दिया गया है, और मेरा कोड तय हो गया है! मैं आपको यह बता रहा हूं क्योंकि आपकी व्याख्या ने मुझे अपने उत्पादन कोड को ठीक करने में मदद की। बहुत बहुत धन्यवाद! – jlafay

    +0

    @CallMeLaNN उत्कृष्ट जानकारी। वही गलती कर रही थी। –

    4

    यह पहले से ही नोट किया गया था के रूप में:

    तो आपरेशन एक अपवाद कि आपके कोड को संभाल नहीं करता है को जन्म देती है, BackgroundWorker अपवाद लग जाती है और RunWorkerCompleted ईवेंट हैंडलर में गुजरता है, जहां यह त्रुटि सिस्टम की संपत्ति के रूप में उजागर किया गया है। कॉम्पोनेंट मॉडेल। RunWorkerCompletedEventArgs।

    जब भी आप मूल धागे से बातचीत कर रहे हों तो यह महत्वपूर्ण है। उदाहरण के लिए यदि आप अपने अपवाद के नतीजे को अपने फॉर्म पर किसी प्रकार के लेबल में लिखना चाहते हैं, तो जब आपको पृष्ठभूमिवर्कर के DoWork में अपवाद नहीं लेना चाहिए, लेकिन इसके बजाय RunWorkerCompletedEventArgs से e.Error को संभालें।

    आप परावर्तक साथ BackgroundWorker कोड का विश्लेषण यदि आप अपने सभी बिल्कुल स्पष्ट संभाला देख सकते हैं: आपका DoWork एक कोशिश पकड़ ब्लॉक में मार डाला जाता है, और अपवाद सिर्फ RunWorkerCompleted को पारित कर दिया है। यही कारण है कि मैं DoWork ईवेंट में अपने सभी अपवादों को हमेशा पकड़ने की 'पसंदीदा' विधि से असहमत हूं।

    संक्षेप में, मूल सवाल का जवाब देने:

    हाँ - आप हमेशा निकाल दिया जा करने के लिए अपने RunWorkerCompleted पर भरोसा कर सकते हैं।

    ई.एरर रनवॉर्कर से अन्य थ्रेड में अपवादों की जांच करने के लिए पूर्ण करें।

    3

    यह विजुअल स्टूडियो से चलने पर डीबगर संलग्न किए बिना ही काम करेगा, डीबगर ड्वॉर्कर विधि में अनचाहे अपवाद को पकड़ लेगा और निष्पादन तोड़ देगा, हालांकि आप जारी रखने पर क्लिक कर सकते हैं और RunWorker पूर्ण हो जाएगा और आप होंगे e.Error फ़ील्ड के माध्यम से अपवाद पढ़ने में सक्षम।

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