2010-05-19 12 views
7

So wurde mir gesagt, was ich hier mache, ist falsch, aber ich bin mir nicht sicher warum.Sind Hintergrundthreads eine schlechte Idee? Warum?

Ich habe eine Webseite, die eine CSV-Datei mit Dokumentnummern importiert, um eine teure Operation durchzuführen. Ich habe die teure Operation in einen Hintergrund-Thread eingefügt, um zu verhindern, dass die Anwendung blockiert wird. Hier ist, was ich kurz gesagt habe.

protected void ButtonUpload_Click(object sender, EventArgs e) 
{ 
    if (FileUploadCSV.HasFile) 
    { 
     string fileText; 
     using (var sr = new StreamReader(FileUploadCSV.FileContent)) 
     { 
      fileText = sr.ReadToEnd(); 
     } 

     var documentNumbers = fileText.Split(new[] {',', '\n', '\r'}, StringSplitOptions.RemoveEmptyEntries); 

     ThreadStart threadStart =() => AnotherClass.ExpensiveOperation(documentNumbers); 
     var thread = new Thread(threadStart) {IsBackground = true}; 
     thread.Start(); 
    } 
} 

(natürlich mit einem gewissen Fehlerprüfung & Nachrichten für Benutzer geworfen)

Also meine dreifache Frage:

  • a) Ist dies eine schlechte Idee?
  • b) Warum ist das eine schlechte Idee?
  • c) Was würden Sie stattdessen tun?

Antwort

8

Ein mögliches Problem besteht darin, dass Ihr Hintergrundthread in Ihrem Websitesanwendungspool ausgeführt wird. IIS kann sich dafür entscheiden, Ihren Anwendungspool zu recyceln, wodurch die teure Operation beendet wird, bevor sie ausgeführt wird.

Ich würde lieber für eine Option gehen, wo ich einen separaten Prozess hatte, möglicherweise ein Windows-Dienst, der die teure Operation Anfragen erhalten und sie außerhalb des asp.net-Prozesses ausführen würde. Dies würde nicht nur bedeuten, dass Ihre teure Operation einen Neustart des Anwendungspools übersteht, sondern auch Ihre Webanwendung vereinfachen, da sie die Verarbeitung nicht verarbeiten muss.

Die Angabe des Dienstes zur Ausführung des teuren Prozesses könnte mithilfe einer Art Interprozesskommunikation erfolgen, der Dienst könnte eine Datenbanktabelle oder eine Datei abrufen oder Sie können eine Verwaltungswarteschlange verwenden, die der Dienst abhört.

Es gibt viele Möglichkeiten, dies zu tun, aber mein Hauptpunkt ist, dass Sie den teuren Prozess von Ihrer Webanwendung trennen sollten, wenn möglich.

1

a: Ja.

Verwenden Sie den ThreadPool;) Warteschlange ein WorkItem - vermeidet den Overhead der Generierung von Tonnen von Threads.

7

Ich empfehle Ihnen die Verwendung der BackgroundWorker Klasse statt Threads direkt zu verwenden. Dies liegt daran, dass BackgroundWorker speziell entwickelt wurde, um Hintergrundoperationen für eine grafische Anwendung durchzuführen, und (unter anderem) Mechanismen zur Übertragung von Aktualisierungen an die Benutzeroberfläche bereitstellt.

+0

Aber 'BackgroundWorker' verwendet' ThreadPool'-Threads, die nicht für lang andauernde Operationen verwendet werden sollten. – Toby

+0

Haben Sie eine Referenz? –

+0

Es hängt auch von der Definition von "long-running" ab. Es gibt einen Unterschied zwischen "lange genug wollen wir den Benutzer nicht sitzen lassen und darauf warten" und "Stunden oder Tage". –

Verwandte Themen