2010-08-24 11 views
5

Innerhalb eines asp.net MVC 2-Controller, habe ich den folgenden Code:ist ein Hintergrundarbeiter in einem Controller async?

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

Meine Frage ist: ist dieser Code Asynchron, dh es einen neuen Thread startet und die Steuerung gibt den Blick, während ‚blah‘ ist parallel ausführen?

Wenn nicht, wie würde ich diese Ergebnisse erzielen?

Antwort

7

In MVC 2 gibt es ein neues Feature namens AsyncController, das die richtige Art ist, Async-Aufrufe in MVC durchzuführen. Ihr Controller sollte von AsyncController anstelle von Controller erben. Dann sollte der Name Ihrer primären Aktionsmethode am Ende "Async" haben. beispielsweise genannt Blah(), wenn Sie eine Aktion Methode haben, nennen Sie in BlahAsync() statt und diese automatisch vom Rahmen erkannt wird (und BlahCompleted() für den Rückruf verwenden):

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(); 
} 

Mehr Infos auf dem AsyncController hier: MVC AsyncController

0

Ich bin nicht sicher, dass dies für Sie arbeiten heraus (ich sage es nicht wird nicht, nur, dass ich bin nicht sicher, ). Die kurze Antwort lautet ja, der Code ist asynchron. Aber um irgendeinen Rückgabewert von einer BackgroundWorker zu erhalten, müssen Sie mit seinem RunWorkerCompleted Ereignis umgehen.

Der grundlegende Mechanismus ist etwas Wert in die e.Result Eigenschaft in Ihrem DoWork Ereignis zu setzen, und dann von der in Ihrem RunWorkerCompleted Ereignis e.Result Eigenschaft abzurufen (sicherstellen, dass zuerst e.Error überprüfen, um zu sehen, ob eine Ausnahme in DoWork geworfen wurde).

Der Grund, warum ich nicht sicher bin, ob es funktioniert, ist, dass Sie das using Schlüsselwort verwenden, das sicherstellt, dass die BackgroundWorker am Ende des Codeblocks entsorgt wird. Da es seine Arbeit asynchron ausführt, kann dies möglicherweise verhindern, dass Sie jemals eine Chance erhalten, mit RunWorkerCompleted umzugehen. Ich bin mir wirklich nicht sicher - vielleicht weiß es jemand anderes?

0

Ich denke, Sie werden wahrscheinlich Probleme auftreten, wie es versuchen wird, den Arbeiter zu entsorgen, während der Hintergrund-Thread noch verwendet wird. Wenn nichts anderes, unvorhersehbares Verhalten.

1

BackgroundWorker ist nicht wirklich das, was Sie hier wollen: Es gibt keine Benutzeroberfläche mit Rückrufen zu aktualisieren. Sie möchten nur ein Arbeitselement zu einem Thread-Pool-Thread auslösen und weitermachen.

Die ThreadPool.QueueUserWorkItem Methode ist wahrscheinlich eine bessere Lösung hier, oder verwenden Sie die neue Task parallel Ansatz: Task.Factory.StartNew(...).

Verwandte Themen