Ausführen einer asynchronen Operation, die von einer ASP.NET-Webseitenanforderung ausgelöst wird
Habe ich ein asynchroner Vorgang, der aus verschiedenen Gründen muss ausgelöst werden, die über einen HTTP-Aufruf ASP.NET web Seite. Wenn meine Seite angefordert wird, sollten Sie beginnen, diese operation und sofort wieder eine Bestätigung an den client.
Diese Methode ist auch ausgesetzt über einen WCF-service, und es funktioniert perfekt.
Bei meinem ersten Versuch, war eine Ausnahme geworfen, der mir sagt:
Asynchrone Operationen sind in diesem Kontext nicht zulässig. Seite starten einer asynchronen operation zu haben, die Async Attribut auf true festgelegt ist, und einen asynchronen Betrieb kann nur sein auf einer Seite gestartet, die vor PreRenderComplete-Ereignis.
Also, natürlich habe ich den Async="true"
parameter der @Page
Richtlinie. Nun, ich bin nicht immer ein Fehler, aber die Seite wird blockiert, bis der Asynchrone Vorgang abgeschlossen ist.
Wie bekomme ich ein true fire-and-forget-Seite arbeiten?
Edit: code für mehr info. Es ist ein bisschen komplizierter als das, aber ich habe versucht, die Allgemeine Idee, die in es.
public partial class SendMessagePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string message = Request.QueryString["Message"];
string clientId = Request.QueryString["ClientId"];
AsyncMessageSender sender = new AsyncMessageSender(clientId, message);
sender.Start();
Response.Write("Success");
}
}
Den AsyncMessageSender Klasse:
public class AsyncMessageSender
{
private BackgroundWorker backgroundWorker;
private string client;
private string msg;
public AsyncMessageSender(string clientId, string message)
{
this.client = clientId;
this.msg = message;
//setup background thread to listen
backgroundThread = new BackgroundWorker();
backgroundThread.WorkerSupportsCancellation = true;
backgroundThread.DoWork += new DoWorkEventHandler(backgroundThread_DoWork);
}
public void Start()
{
backgroundThread.RunWorkerAsync();
}
...
//after that it's pretty predictable
}
InformationsquelleAutor der Frage Damovisa | 2009-03-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie nicht kümmern, über die Rückkehr alles, um den Nutzer sind, können Sie einfach starten Sie entweder einen eigenen thread oder für einen quick-and-dirty Ansatz, verwenden Sie ein delegate und invoke es asynchrnously. Wenn Sie kümmern sich nicht um den Benutzer zu Benachrichtigen, wenn die asynchrone Aufgabe abgeschlossen ist, können Sie Sie ignorieren den Rückruf. Versuchen Sie setzen einen breakpoint am Ende der SomeVeryLongAction () - Methode, und du wirst sehen, dass es die Ausführung beendet, nachdem die Seite bereits serviert:
InformationsquelleAutor der Antwort Ilya Tchivilev
OK, hier ist das problem: das Async-Attribut ist für den Fall, dass die Seite gehen, um eine lang andauernde Aufgabe, die ebenfalls blockiert den thread, und dann deine Seite muss die Ausgabe von dieser Aufgabe, um wieder die info an den Benutzer. Zum Beispiel, wenn Ihre Webseite benötigt für den Aufruf eines web-service, warten auf seine Antwort, und verwenden Sie dann die Daten aus der Antwort zu Rendern Ihrer Seite.
Der Grund, warum Sie verwenden würden, das Async-Attribut ist zu vermeiden, blockiert der thread. Dies ist wichtig, weil ASP.NET Anwendungen die Verwendung eines thread-pool, um Anfragen zu bedienen, und es gibt nur eine relativ kleine Anzahl von threads zur Verfügung. Und wenn jeder Anruf, bindet das der thread während der Wartezeit auf die web-service-Aufruf, dann bald wirst du genug Treffer gleichzeitige Benutzer, Benutzer gehen zu müssen, zu warten, bis diese web-service-Aufrufe. Das Async-Attribut können Sie den Faden zurück in den threadpool und dienen anderen gleichzeitigen Besucher zu Ihrer web site, anstatt Sie zu zwingen, still zu sitzen, nichts zu tun während der Wartezeit für die web-service-Aufruf zurückkehren.
Das Ergebnis für Sie ist: das Async-Attribut ist speziell für den Fall, wo du nicht Rendern der Seite, bis die asynchrone Aufgabe abgeschlossen ist, und das ist, warum es nicht Rendern der Seite sofort.
Müssen Sie starten Sie Ihren eigenen thread, und machen es zu einem daemon-thread. Ich erinnere mich nicht an die genaue syntax, aber Sie können leicht finden es in der doc von der Suche des BCL-doc für "daemon". Das bedeutet der thread wird halten Sie Ihre Anwendung, Herunterfahren, während es am Leben ist, was wichtig ist, da ASP.NET und IIS das Recht vorbehalten, "Recycling-Prozess", wenn Sie es für erforderlich halten, und wenn das passiert, während Ihr thread arbeitet, Ihre Aufgabe wird gestoppt. Macht den thread-daemon wird verhindern, dass diese (außer für einige mögliche seltene Grenzfälle ... du wirst mehr erfahren, wenn Sie die Dokumentation, die auf dieser).
Dass daemon-thread ist, wo Sie kick-off-diese Aufgaben. Und nachdem Sie gesagt haben, die daemon-thread, die Aufgabe zu tun, können Sie sofort Rendern Ihrer Seite ... also die Darstellung der Seite wird sofort geschehen.
Sogar besser als ein daemon-thread in Ihrem ASP.NET Prozess, obwohl, wäre die Umsetzung in ein Windows-Dienst, der für die Durchführung der Aufgabe. Haben Sie Ihre ASP.NET Anwendung die Kommunikation die Aufgabe, die durchgeführt werden, um den Service. Keine Notwendigkeit für einen daemon-thread und kein Grund zur Sorge über Ihre ASP.NET Prozess recycelt. Wie Sie sagen, der Dienst, die Aufgabe zu tun? Vielleicht durch WCF, oder vielleicht durch das einfügen eines Datensatzes in eine Datenbank-Tabelle, die die Service-Umfragen. Oder eine Reihe von anderen Möglichkeiten.
EDIT: Hier ist eine weitere Idee, die ich zuvor verwendet haben, aus diesem sehr gleichen Zweck. Schreiben Sie die info über Ihre Aufgabe in einer MSMQ-Warteschlange. Haben, einem anderen Prozess (vielleicht sogar auf einem anderen Rechner) ziehen aus dieser Warteschlange und machen die zeitaufwändige Aufgabe. Die Aufgabe einfügen in eine Queue ist optimiert, um so schnell wie möglich zurückgeben, damit dein thread wird nicht blockiert, während die Daten, die Sie in die Warteschlange gesendet wird, über den Draht oder etwas ähnliches. Es ist einer der schnellsten Wege, um Notiz von der Tatsache, dass eine Aufgabe erledigt werden muss, ohne zu warten, für diese Aufgabe auszuführen.
InformationsquelleAutor der Antwort Charlie Flowers
Wenn Sie mit webforms gesetzt Ansync = "true" in Ihrem .aspx-Seite, wo Sie machen die Anfrage.
<%@ Page Language="C#" Async="true" ... %>
InformationsquelleAutor der Antwort vikingben
Können Sie diese Einschränkung umgehen, ganz einfach und sogar ohne Einstellung Async true.
InformationsquelleAutor der Antwort Serge
Wenn man diesen Fehler beim Aufruf von web service asynchron, stellen Sie sicher, hinzufügen des Async='true' - Attribut, wie angewiesen, durch die
Ausnahmemeldung?
oben auf der Seite < Page Language='VB' Async= "true" AutoEventWireup= "false"
CodeFile='mynewpage.aspx.vb' Inherits='mynewpage' %>
InformationsquelleAutor der Antwort Amrik