2012-06-18 15 views
14

क्या मैं किसी विधि में पृष्ठभूमि कार्यकर्ता को परिभाषित कर सकता हूं?पृष्ठभूमि कार्यकर्ता और कचरा संग्रह?

private void DownLoadFile(string fileLocation){ 
    BackgroundWorker worker = new BackgroundWorker(); 

    worker.DoWork += new DoWorkEventHandler((obj, args) => { 
     // Will be executed by back ground thread asynchronously. 
     args.Result = Download(fileLocation); 
    }); 

    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, args) => { 
     // will be executed in the main thread. 
     Result r = args.Result as Result; 
     ReportResult(r); 
    }); 

    worker.RunWorkerAsync(fileLocation); 
} 

प्रश्न: डाउनलोड() फ़ंक्शन एक लंबे समय फ़ाइल डाउनलोड करने के लिए लेता है, जी सी में लात और RunWorkerCompleted से पहले कार्यकर्ता वस्तु एकत्र कर सकते हैं() निष्पादित किया जाता है?

+0

मैं एक प्रतिनिधि (एक्शन (स्ट्रिंग) का उपयोग करने की सिफारिश करता हूं) और फिर BeginInvoke को कॉल करने की सलाह दूंगा। मुझे इस कोड में BackgroundWorker की कोई आवश्यकता नहीं दिखाई दे रही है। जब भी विधि पूरी की जाती है तब भी आप एक ईवेंट संलग्न कर सकते हैं। – JDB

+1

ऐसा करने का एक बेहतर तरीका 'QueueUserWorkItem' का उपयोग करके थ्रेड पूल कतार में जोड़ना होगा: http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx –

+0

@J ... थ्रेडपूल अच्छा है, लेकिन यह सही सिंक्रनाइज़ेशन कॉन्टेक्स्ट * पर कॉलबैक * को संभालने में आसान बनाता है। टीपीएल उस अच्छी तरह से संभालती है, यद्यपि। –

उत्तर

12

यह देखते हुए कि आप वास्तव में BackgroundWorker की कार्यक्षमता का ज्यादा उपयोग नहीं कर रहे, मैं इस के बजाय के लिए TPL का उपयोग कर की सिफारिश करेंगे:

private void DownLoadFile(string fileLocation) 
{ 
    Task.Factory.StartNew(() => Download(fileLocation)) 
     .ContinueWith(t => ReportResult(t.Result), TaskScheduler.FromCurrentSynchronizationContext()); 
} 

कहा जा रहा है, worker वस्तु कचरा नहीं होगा एक बार यह चलने के बाद एकत्रित किया जाता है, क्योंकि थ्रेडपूल धागा स्वयं कार्यकर्ता को "प्रयुक्त वस्तु" के रूप में रखेगा। कचरा कलेक्टर पूरा होने के बाद तक इसे इकट्ठा नहीं कर पाएगा जब तक कि ईवेंट हैंडलर निष्पादित नहीं हो जाता है, उस समय पर कोई उपयोगकर्ता कोड नहीं होगा जो BackgroundWorker के उदाहरण तक पहुंच सकता है।

इसके अलावा, यह संभावना इस वर्ग के उदाहरण जा रहा कचरा एकत्र से, रखना होगा के रूप में उदाहरण के तरीके (ReportResults) बंद करने के लिए प्रयोग किया जाता का उदाहरण रखना "इस" सुलभ और जीसी के लिए पात्र नहीं।

+0

यह वास्तव में ओपी के प्रश्न का उत्तर नहीं है। हालांकि अभी भी अच्छी सलाह है। – JDB

+1

@ Cyborgx37 ओपी के प्रश्न का सीधा जवाब जोड़ा गया। –

+0

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

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