2010-08-24 9 views
5

एक asp.net MVC 2 नियंत्रक के अंदर, मैं निम्नलिखित कोड है:एक नियंत्रक async में एक पृष्ठभूमि कार्यकर्ता है?

using (BackgroundWorker worker = new BackgroundWorker()) 
         { 
          worker.DoWork += new DoWorkEventHandler(blah); 
          worker.RunWorkerAsync(var); 
         } 

मेरे सवाल यह है: इस कोड को async, है, जिसका अर्थ यह एक नया धागा की शुरूआत और नियंत्रक दृश्य देता है, जबकि 'blah' है समानांतर में निष्पादन?

यदि नहीं, तो मैं इन परिणामों को कैसे प्राप्त करूं?

उत्तर

7

एमवीसी 2 में एसिंक कंट्रोलर नामक एक नई सुविधा है जो एमवीसी में एसिंक कॉल करने का सही तरीका है। आपके नियंत्रक को नियंत्रक के बजाय AsyncController से उत्तराधिकारी होना चाहिए। फिर आप अपने प्राथमिक क्रिया विधि नाम के अंत में "Async" होना चाहिए। उदाहरण के लिए, आप एक कार्रवाई विधि ब्ला() कहा जाता था, तो आप BlahAsync में) का नाम (बजाय और यह स्वचालित रूप से ढांचा द्वारा मान्यता प्राप्त हो जाएगा (और कॉलबैक के लिए BlahCompleted() का उपयोग):

public virtual void BlahAsync() 
{ 
    AsyncManager.OutstandingOperations.Increment(); 
    var service = new SomeWebService(); 
    service.GetBlahCompleted += (sender, e) => 
     { 
      AsyncManager.Parameters["blahs"] = e.Result; 
      AsyncManager.OutstandingOperations.Decrement(); 
     }; 
    service.GetBlahAsync(); 
} 

public virtual ActionResult BlahCompleted(Blah[] blahs) 
{ 
    this.ViewData.Model = blahs; 
    return this.View(); 
} 

और जानकारी AsyncController पर यहां: MVC AsyncController

0

मुझे यकीन है कि यह आप के लिए बाहर काम करेंगे नहीं हूँ (मैं इसे नहीं होगा यह नहीं कह रहा हूँ, सिर्फ इतना है कि मुझे यकीन है कि नहीं कर रहा हूँ)।

संक्षिप्त उत्तर हाँ है, कोड असीमित है। लेकिन BackgroundWorker से किसी भी प्रकार का रिटर्न वैल्यू प्राप्त करने के लिए, आपको इसकी RunWorkerCompleted ईवेंट को संभालने की आवश्यकता है।

बुनियादी तंत्र को अपने RunWorkerCompleted घटना में e.Result संपत्ति से प्राप्त कर (देखने के लिए अगर एक अपवाद DoWork में फेंक दिया गया था पहले e.Error जाँच करने के लिए सुनिश्चित करने के अपने DoWork घटना में e.Result संपत्ति में कुछ मूल्य डाल करने के लिए, और उसके बाद है)।

कारण मुझे यकीन नहीं है कि यह काम करेगा या नहीं, यह है कि आप using कीवर्ड का उपयोग कर रहे हैं, जो सुनिश्चित करता है कि BackgroundWorker कोड ब्लॉक के अंत में निपटाया गया है। चूंकि यह अपने काम को असीमित रूप से कर रहा है, यह आपको RunWorkerCompleted को संभालने का मौका मिलने से रोक सकता है या नहीं। मुझे सच में यकीन नहीं है - शायद किसी और को पता है?

0

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

1

BackgroundWorker वास्तव में आप यहां क्या चाहते हैं: कॉल बैक के साथ अपडेट करने के लिए कोई यूआई नहीं है। आप सिर्फ एक थ्रेड पूल थ्रेड पर एक कार्य आइटम को आग लगाना चाहते हैं और आगे बढ़ना चाहते हैं।

ThreadPool.QueueUserWorkItem विधि शायद यहां बेहतर फिट है, या नए कार्य समानांतर दृष्टिकोण का उपयोग करें: Task.Factory.StartNew(...)

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