2009-03-05 37 views
9

मैंने हाल ही में "क्लासिक" धागे के बजाय पृष्ठभूमि कार्यकर्ता का उपयोग करने की कोशिश की और मुझे यह महसूस हो रहा है कि यह मेरे लिए कम से कम, समाधानों की तुलना में अधिक समस्याएं पैदा कर रहा है। मेरे पास एक बैकग्राउंडर है जो एक सिंक्रोनस रीड चला रहा है (इस मामले में सीरियलपोर्ट से) और 1 कोड लाइन में लगभग 30 सेकंड अवरुद्ध हो रहा है, तो रद्दीकरण समाधान समाधान नहीं है। मैं देख रहा हूं कि अगर इस बिंदु पर एप्लिकेशन बंद हो जाता है (या तो क्रॉस बटन और एप्लिकेशन.एक्सिट() के साथ) प्रक्रिया ज़ोंबी हमेशा के लिए रखती है।पृष्ठभूमि कार्यकर्ता निरस्त

मुझे पृष्ठभूमि कार्यकर्ता थ्रेड को निरस्त करने या मारने के लिए एक तरीका चाहिए।

उत्तर

2

मुझे पूरा करने की कोशिश करने की कोशिश करने पर मुझे पूरा यकीन नहीं है, लेकिन शायद SerialPort.DataReceived ईवेंट एक बेहतर समाधान है?

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

इसके अलावा, मुझे धागे को रद्द करने का विचार पसंद नहीं है। यह खतरनाक लगता है, और बहुप्रचारित अनुप्रयोगों को और अधिक जोखिम लेने की आवश्यकता नहीं है।

+0

मैंने पाया SerialPort.DataReceived एक सा सीएफ में भ्रमित हो, अगर impl एफएफ में बेहतर है पता नहीं है। सीएफ एक अपेक्षाकृत अधिक थ्रेड का उपयोग करता है, जिससे आप उम्मीद कर सकते हैं। – Quibblesome

+10

पृष्ठभूमिवर्कर के बारे में टिप्पणी के लिए लगभग 1 तक लुभाना; यह यूआई थ्रेड में कुछ मानकों और स्वचालित रूप से मार्शल इवेंट्स को लागू करने के लिए डिज़ाइन किया गया है, जो इसके उपयोग के वैध कारण हैं; थ्रेडिंग को समझने से समस्याएं पैदा नहीं होंगी इससे कोई फर्क नहीं पड़ता कि आप किस तरह से जाते हैं। –

+0

जब तक सामान्य थ्रेड से UI थ्रेड के साथ सिंक्रनाइज़ करने का कोई आसान तरीका न हो ... – Glimpse

2

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

3

प्रक्रिया ज़ोंबी नहीं बननी चाहिए, क्योंकि पृष्ठभूमिवर्कर थ्रेड को "पृष्ठभूमि" के रूप में चिह्नित किया गया है और यूआई बंद होने पर समाप्त होना चाहिए।

+0

यह सच है क्योंकि बीडब्ल्यू दृश्यों के पीछे थ्रेडपूल क्लास का उपयोग कर रहा है। –

5

मैंने एक साथ रखा है (मुझे लगता है) नौकरी करता है। अगर मुझे लगता है तो कृपया मुझे बताएं। यह कैसे काम करता है इसका एक सरल उदाहरण है।

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true}; 

backgroundWorker.DoWork += (sender, args) => 
     {     
       var thisWorker = sender as BackgroundWorker; 
       var _child = new Thread(() => 
               { 
                //..Do Some Code 

               }); 
       _child .Start(); 
       while (_child.IsAlive) 
       { 
        if (thisWorker.CancellationPending) 
        { 
         _child.Abort(); 
         args.Cancel = true; 
        } 
        Thread.SpinWait(1); 
       }     
     }; 

backgroundWorker.RunWorkerAsync(parameter); 
//..Do Something... 
backgroundWorker.CancelAsync(); 

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

कृपया मुझे बताएं कि क्या मैं दीवार के खिलाफ अपने सिर को टक्कर लगी हूं लेकिन ऐसा लगता है कि यह ठीक काम करता है .. लेकिन थ्रेड के साथ समस्या यह नहीं है .. अलग-अलग समय पर आप इसे चलाने के दौरान अलग-अलग परिणाम प्राप्त कर सकते हैं।

+0

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

0

आप इस कोशिश कर सकते हैं:

  backgroundworker.Dispose(); 
      backgroundworker = null; 
      GC.Collect(); //this helps cleans up ram 
संबंधित मुद्दे