2012-06-01 13 views
11

Ich muss eine unendliche while-Schleife ausführen und die Ausführung in global.asax initiieren. Meine Frage ist, wie genau soll ich es tun? Soll ich einen neuen Thread starten oder sollte ich Async und Task oder etwas anderes verwenden? Innerhalb der While-Schleife muss ich tun await TaskEx.Delay(5000);Hintergrundprozess korrekt implementieren Thread in ASP.NET

Wie mache ich das, damit es keine anderen Prozesse blockiert und Speicherlecks nicht erstellen?

Ich benutze VS10, AsyncCTP3, MVC4

EDIT:

public void SignalRConnectionRecovery() 
     { 
      while (true) 
      { 
       Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString()); 
       await TaskEx.Delay(5000); 
      } 
     } 

Alles, was ich tun müssen, ist dies als eine Singleton-Instanz laufen global solange Anwendung verfügbar ist.

EDIT: behobenes

Dies ist die letzte Lösung in Global.asax

protected void Application_Start() 
{ 
    Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery); 
    signalRConnectionRecovery.IsBackground = true; 
    signalRConnectionRecovery.Start(); 

    Application["SignalRConnectionRecovery"] = signalRConnectionRecovery; 
} 


protected void Application_End() 
{ 
    try 
    { 
     Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"]; 
     if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive) 
     { 
      signalRConnectionRecovery.Abort(); 
     } 
    } 
    catch 
    { 
      /// 
    } 
} 

ich diesen schönen Artikel über gefunden, wie async Arbeiter verwenden: http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

Und: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Aber ich denke für meine Notwendigkeit s dieses wird perfekt sein: http://forums.asp.net/t/1433665.aspx/1

+0

Was Sie versuchen zu tun? – jrummell

+1

Was macht Clients.SetConnectionTimeStamp? Was ist der Zweck davon? Welche spezifische Funktionalität möchten Sie implementieren? Wenn Sie eine qualitativ hochwertige Antwort wünschen, müssen Sie diese Informationen bereitstellen. – cadrell0

+0

Dies ist besser mit einem Timer zu tun. – Aristos

Antwort

1

Ich fand diesen schönen Artikel über die Verwendung von Async-Worker, wird es versuchen. http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

Und: http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

Aber ich denke, für meine Bedürfnisse wird dies ein perfekt sein: http://forums.asp.net/t/1433665.aspx/1

+0

Vorsicht - die Endlosschleife wird Ihren Prozessor zerkauen. Außerdem müssen Sie sicherstellen, dass Sie nicht versehentlich mehrere Instanzen dieser Dinge starten (was einige Multithreading-Prüfungen beinhaltet). – JDB

+0

@ Cyborgx37 Nun, das ist, warum ich die OP gebucht haben, aber leider auf, so gibt es zu viel Lärm ... Auch wenn Sie die OP selbst gelesen hatte, dass der Faden, so gibt es zu einem langen Schlaf versetzt wird bekannt hätte ist dort kein CPU-Problem. –

13

ASP.NET ist nicht entworfen, um diese Art von Anforderung zu behandeln. Wenn Sie etwas benötigen, um ständig zu laufen, sollten Sie einen Windows-Dienst erstellen.

aktualisieren

ASP.NET wird für lange laufende Aufgaben nicht ausgelegt ist. Es wurde entwickelt, um schnell auf HTTP-Anfragen zu antworten. Siehe Cyborgx37's answer oder Can I use threads to carry out long-running jobs on IIS? aus ein paar Gründen warum.

aktualisieren

Nachdem Sie nun endlich mit SignalR erwähnt Sie arbeiten, ich sehe, dass Sie versuchen, SignalR in ASP.NET zu hosten, nicht wahr? Ich denke, Sie gehen hier in die falsche Richtung, siehe das Beispiel NuGet package, das auf der project wiki verwiesen wird. In diesem Beispiel wird ein IAsyncHttpHandler zum Verwalten von Aufgaben verwendet.

+2

Der erste Link gibt keinen Grund, warum überhaupt der zweite Link nur die offensichtlichen Bedenken aufzeigt, dass der Server den App-Pool irgendwann recyceln könnte. Ich habe noch eine gültige Sorge zu hören, warum dies eine "schlechte Idee" ist. Um zu implementieren etwas aus in ein Windows-Dienst, so dass Ihre Anwendung viel schwieriger Faktor, klingt wie die schlechte Idee zu mir. Hat jemand einen guten Grund hat, oder ist dies nur Ideologie? – John

+0

_... sehr offensichtlich Sorge, dass der Server wählen könnte den App-Pool irgend point_ zu recyceln, dass eine ziemlich große Sache ... – jrummell

+0

Alle Anwendungen an einem gewissen Punkt gehen, ist das zu ASP.NET nicht eindeutig. Sie streiten sich gegen die Ausführung von Hintergrundjobs in WinForms-Anwendungen, weil der Benutzer jederzeit auf die Schaltfläche zum Schließen klicken kann? Selbst Windows-Dienste müssen heruntergefahren werden, wenn der Server neu gestartet wird. Wie ist das anders? – John

8

Sie können einen Thread in Ihrem global.asax starten, jedoch wird es nur ausgeführt, bis Ihr asp.net-Prozess recycelt wird. Dies geschieht mindestens einmal am Tag oder wenn niemand Ihre Website verwendet. Wenn der Prozess wiederverwendet wird, wird der Thread nur dann neu gestartet, wenn Sie einen Treffer auf Ihrer Website haben. Der Thread wird also nicht fortlaufend ausgeführt.

Um einen kontinuierlichen Prozess zu erhalten, ist es besser, einen Windows-Dienst zu starten.

Wenn Sie die 'in Bearbeitung' Lösung machen, hängt es wirklich davon ab, was Sie tun. Der Thread selbst verursacht keine Probleme im Speicher oder in Deadlocks. Sie sollten ein Meganism hinzufügen, um Ihren Thread zu stoppen, wenn die Anwendung beendet wird. Andernfalls dauert der Neustart sehr lange, da er auf das Anhalten des Threads wartet.

+1

Ausgezeichnet! Ich habe keine Probleme damit, sie zu recyceln. Das ist eine der Anforderungen. –

+0

Danke! Ich habe meine Frage mit mehr Details bearbeitet. –

+0

Ich stimme mit Peer überein. Die Lösung und eine Warnung vor den Gefahren dieser können in diesem großen Artikel: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in- asp-net.aspx/ –

2

Es hängt davon ab, was Sie in Ihrer while-Schleife erreichen möchten, aber im Allgemeinen ist dies die Situation, in der Windows Service die beste Antwort ist. Für die Installation eines Windows-Dienstes müssen Sie Administratorrechte auf dem Webserver haben.

Mit einer Endlosschleife Sie am Ende mit einer Reihe von Problemen, die die Windows-Nachrichtenpumpe. Dies ist die Sache, die eine Windows-Anwendung am Leben erhält, selbst wenn die Anwendung nichts "tut". Ohne es endet ein Programm einfach.

Das Problem mit einer Endlosschleife ist, dass die Anwendung festhält, etwas "zu tun", was andere Anwendungen (oder Threads) daran hindert, ihr Ding "zu machen". Es gab einige Problemumgehungen, wie die DoEvents in Windows Forms, aber alle haben einige gravierende Nachteile in Bezug auf Reaktionsfähigkeit und Ressourcenmanagement. (Akzeptabel in einer kleinen LOB-Anwendung, vielleicht nicht auf einem Webserver.) Selbst wenn die while-Schleife in einem separaten Thread ist, verbraucht sie die gesamte verfügbare Verarbeitungsleistung.

Die asynchrone Programmierung ist eher für lang andauernde Prozesse gedacht, z. B. um zu warten, dass eine Datenbank ein Ergebnis zurückgibt oder darauf, dass ein Drucker online geht. In diesen Fällen ist es der externe Prozess, der eine lange Zeit in Anspruch nimmt, keine Zeitschleife.

Wenn ein Window-Service nicht möglich ist, denke ich, dass es am besten ist, einen separaten Thread mit einer eigenen Nachrichtenpumpe einzurichten, aber das ist ein bisschen kompliziert. Ich habe es noch nie auf einem Webserver gemacht, aber Sie könnten möglicherweise eine Anwendung starten. Dadurch erhalten Sie eine Nachricht und können auf Windows-Ereignisse reagieren. Das einzige Problem ist, dass dies eine Windows-Anwendung startet (entweder WPF oder WinForms), die auf einem Webserver möglicherweise nicht wünschenswert ist.

Was möchten Sie erreichen? Gibt es einen anderen Weg, wie du das machen könntest?

+0

Danke! Ich habe meine Frage mit mehr Details bearbeitet. –

Verwandte Themen