2013-02-11 20 views
8

Umwelt:Verarbeitet ASP.NET eine Anfrage auch dann zuverlässig weiter, wenn ein Benutzer über Javascript navigiert wurde?

  • Windows Server 2003 - IIS 6.x
  • ASP.NET 3.5 (C#)
  • IE 7,8,9
  • FF (was auch immer die neuesten Versionen sind 10)

Benutzerszenario:

Der Benutzer gibt Suchkriterien für große Datenmengen ein. Nach dem Einleiten der Anfrage werden sie zu einer Ergebnisseite geleitet, wo sie warten, bis die Daten geladen sind, und dann die Daten verfeinern können.

Technisches Szenario:

Nach Benutzern Suchkriterien senden (über Ajax-Aufruf), UI ruft Back-End-Service. Der Back-End-Dienst fragt Transaktionssystem (e) ab und legt die resultierenden Daten in einen db- "Cache" - eine denormalisierte Tabelle - ein, um die Daten weiter zu verfeinern (d. H. Sortieren, filtern). UI wartet, bis die Daten zwischengespeichert sind, und navigiert zu einer resultierenden Seite, nachdem sie benachrichtigt wurde, dass der Vorgang abgeschlossen ist. Die resultierende Seite ruft dann auf, um die Daten aus der denormalisierten Tabelle abzurufen.

Problem:

Die Suche ist relativ langsam (15-25 Sekunden) für große Abfragen, die viele Systeme auf den eingegebenen Kriterien abgefragt werden am Ende mit. Es ist relativ schnell für andere Abfragen (< 4 Sekunden).

Technische Einschränkungen:

  1. Wir können nicht völlig neu Architekt diese Suche/Ergebnisse System. Es gibt viel zu viele Komplexitäten zwischen der UI und dem Back-End. Die Seite ist erforderlich (aufgrund von Einschränkungen, die in StackOverflow nicht gelöst werden können), um nach der Ausführung der Suchkriterien zu drehen.

  2. Wir können die Organisation auch nicht bitten, die Daten vor der Suche zu denormalisieren, da die Daten in Echtzeit sein müssen, dh wenn ein Benutzer Änderungen an anderen Systemen vornimmt, müssen die Daten korrekt angezeigt werden eine Suche danach.

Prozess, der ich folgen möchten:

  1. Ich möchte ein wenig betrügen. Ich möchte die "Cache" -Anfrage über einen asynchronen HttpHandler in einem Fire-Forget-Modell ausgeben.

  2. Nach der Abfrage möchte ich die Seite auf die resultierende Seite überführen.

  3. Auf der Übergangsseite möchte ich die "Cache" -Tabelle abfragen, um zu sehen, ob die Daten noch eingefügt wurden.

  4. Der Grund, warum ich diesen Übergang sofort machen möchte, ist, dass die resultierende Seite teuer ist (auch ohne die Daten zu bekommen) - immer noch 2 Sekunden Ladezeit, bevor man den Dienst aufruft, der die Daten bekommt aus dem Cache.

Frage:

Wird der ASP.NET Thread, die Verarbeitung weiterhin zuverlässig über die Asynchron-Handler aufgerufen wird, auch wenn ich von der Seite navigieren weg ein Javascript-Weiterleitung?

Technische Grenzen 2:

Ja, ich weiß ... Dieser Suchvorgang klingt nicht effizient. Daran kann ich momentan nichts ändern. Ich versuche, alles zu tun, um es etwas besser zu machen, während wir weiter nachforschen, wie wir es umgestalten werden.

Wenn Ihre Antwort lautet: "Werfen Sie es weg und fangen Sie von vorne an", antworten Sie bitte nicht. Das ist nicht akzeptabel.

+0

Ok, lass mich sehen, ob ich es bekommen habe. Wenn die Benutzer einige Suchkriterien senden, starten Sie die Abfrageausführung asynchron und leiten den Benutzer sofort zur Ergebnisseite um. Anschließend laden Sie auf der Ergebnisseite die Seite und überprüfen, ob die Abfrage auf dem Server beendet ist, um die Ergebnisse für den Benutzer anzuzeigen. Und Sie fragen, ob die Ausführung der asynchronen Abfrage weiterhin ausgeführt wird, wenn der Benutzer die Ergebnisseite verlässt? Ist das korrekt? –

+0

Das ist fast richtig. Die Frage ist nicht, ob es weiter ausgeführt wird, wenn der Benutzer die Ergebnisseite verlässt, sondern eher weiter ausgeführt wird, wenn der Benutzer auf die Ergebnisseite übertragen wird. Bei dem Testen auf meinem lokalen Computer scheint die asynchrone Operation weiterhin ausgeführt zu werden. Ich möchte jedoch überprüfen, wie zuverlässig dieser Prozess ist. Ist dies das entworfene Verhalten von ASP.NET oder ein Fall von "es funktioniert auf meiner Maschine"? –

+0

Wenn Sie den Threading-Namespace verwenden (sind Sie?), Um einige Verarbeitung asynchron auf dem Webserver auszuführen, glaube ich nicht, dass es ein "es funktioniert auf meinem Computer" Fall wäre. Es sollte auf jeden Fall wie erwartet auf IIS funktionieren. –

Antwort

4

Ja.

Es gibt die Eigenschaft Response.IsClientConnected, die verwendet wird, um zu wissen, ob ein lang andauernder Prozess noch verbunden ist. Der Grund für diese Eigenschaft ist, dass Prozesse auch dann weiter ausgeführt werden, wenn die Verbindung zum Client unterbrochen wird und sie manuell über die Eigenschaft erkannt werden müssen, und manuell heruntergefahren werden muss, wenn eine vorzeitige Unterbrechung auftritt. Es ist nicht standardmäßig einen laufenden Prozess beim Trennen des Clients zu beenden.

Verweis auf dieses Angebot: http://msdn.microsoft.com/en-us/library/system.web.httpresponse.isclientconnected.aspx

Update

FYI dies eine sehr schlechte Eigenschaft ist mit Steckdosen an diesen Tagen zu verlassen.Ich rate Ihnen dringend, einen Ansatz zu machen, der es Ihnen ermöglicht, schnell eine Anfrage zu vervollständigen, die in einer Datenbank oder einer Warteschlange eine lang andauernde Aufgabe erledigt, wahrscheinlich RabbitMQ oder etwas ähnliches, das wiederum socket.io oder ähnliches verwendet, um zu aktualisieren Die Webseite oder App wird einmal fertiggestellt.

+0

Danke für den Link. Ich habe deine Antwort akzeptiert. Die einzige Frage, die bleibt, ist, dass ich diese Logik scheinbar finden kann. "Grund für diese Eigenschaft ist, dass Prozesse auch dann weiterlaufen, wenn der Client getrennt wird und manuell über die Eigenschaft erkannt wird und manuell heruntergefahren wird, wenn eine vorzeitige Trennung auftritt. "Auf dieser Quelle. Im Wesentlichen geben Sie an, dass sobald ein Thread beginnt, er beendet wird, es sei denn, etwas Außergewöhnliches passiert. –

+0

Ja. Das habe ich auch in der Praxis erlebt. Zum Beispiel schrieb ich einen langwierigen Prozess, der durch einen Webseitentreffer ausgelöst wurde. Ein statisches Element wurde umgeschaltet, um anzuzeigen, ob der Prozess ausgeführt wurde oder nicht. Die Seitenanforderung würde antworten, wenn "Ingest noch in Bearbeitung ist, versuchen Sie es später erneut", wenn das statische Flag wahr war.Ich könnte gehen und im selben Browserfenster zurückkommen und der Prozess würde sich nicht trennen, und es verhält sich wie erwartet wie ein normales statusbehaftetes Programm während des Prozesses und würde die Flagge nach Abschluss des Vorgangs zuverlässig auf false zurückschalten (vorausgesetzt, try-catch)). –

3

Wie wäre es mit der asynchronen Operation in einem ASP.NET-Thread überhaupt nicht? Lassen Sie den ASP.NET-Code einen Dienst aufrufen, um die Datensuche in die Warteschlange einzureihen, und kehren Sie dann mit einem Token aus dem Dienst zum Browser zurück, wo er dann zur Ergebnisseite umgeleitet wird, die auf das abgeschlossene Ergebnis wartet? Die Ergebnisseite fragt das Token vom Dienst ab.

Auf diese Weise müssen Sie sich keine Gedanken darüber machen, ob ASP.NET irgendwie erfährt, dass der Browser auf eine andere Seite gewechselt ist.

+0

Eine andere Quelle erzählte mir von dieser Art von Lösung. Im Wesentlichen müssten wir irgendeine Art von Hintergrunddienst (höchstwahrscheinlich außerhalb von ASP.NET) haben, der nach hinzugefügten Tokens überwacht, die Suche ausführt und dann das Token aktualisiert, nach dem die Suche durchgeführt wird? Das hört sich gut an, abgesehen von einem kleinen Vorbehalt. Wir wollen die "schnellen" Suchen (wenn möglich) nicht verlangsamen. Aber dies ist möglicherweise der Weg, den wir gehen müssen, wenn wir ohne große Änderungen der Architektur mehr Konsistenz in unserer Leistung schaffen wollen. Ich bin immer noch neugierig auf die Interna des ASP.NET-Verhaltens. –

+0

Der Dienst müsste nicht "überwachen". Es wäre ein WCF-Dienst, der auf eine Anfrage mit den Suchkriterien wartet. Es würde die Kriterien beibehalten, ein Token zurückgeben, das die Anfrage darstellt, und dann mit der Verarbeitung der Suche beginnen. Es würde den Fortschritt der Suche verfolgen. Wenn sie später nach dem Fortschritt gefragt werden, würde sie über den Fortschritt berichten. Wenn es abgeschlossen ist, würde es die Ergebnisse der Suche zurückgeben. –

+0

Wenn Sie im Voraus bestimmen können, dass die "schnelle" Suche schnell erfolgen soll, können Sie diese Suche "in-line" durchführen. In der Tat könnte die ASP.NET-Seite eine Sekunde warten. Fragen Sie dann den Dienst, ob er fertig ist. Wenn nicht, dann gehe zur Seite "Warten auf Ergebnisse". –

0

Eine andere Option ist das Threading (System.Threading).
Wenn der Benutzer die Suchkriterien sendet, beginnt der Server mit der Verarbeitung der Seitenanforderung, erstellt einen neuen für die Ausführung der Suche zuständigen Thread und beendet die Antwort zurück an den Browser und leitet die Ergebnisseite weiter, während der Thread weiterhin ausgeführt wird der Serverhintergrund.
Die Ergebnisseite würde weiterhin auf dem Server überprüfen, ob die Ausführung der Abfrage beendet wurde, da der gestartete Thread die Fortschrittsinformationen teilen würde. Wenn dies abgeschlossen ist, werden die Ergebnisse zurückgegeben, wenn der nächste Ajax-Aufruf von der Ergebnisseite ausgeführt wird.

Es könnte auch mit WebSockets in Betracht gezogen werden. In einem Sinne, dass der Webserver selbst dem Browser mitteilen könnte, wenn er die Abfrageausführung abarbeitet, da er Vollduplex-Kommunikationskanäle bietet.

+0

Während ich Ihre Antwort zu schätzen weiß, bin ich auf der Suche nach einer autoritativen Antwort auf "Wird der ASP.NET-Thread, der über den asynchronen Handler aufgerufen wird, die Verarbeitung zuverlässig fortsetzen, auch wenn ich mit einem JavaScript-Redirect von der Seite weg navigiere?" –

+0

Der neu erstellte Thread läuft alleine auf dem Server und hat keinerlei Verbindung zur Seite des Browsers (staatenlos). Es gibt keine Beziehung zwischen ihnen, die dazu führen könnte, dass der Thread beendet wird, wenn der Benutzer auf eine andere Seite umleitet. Aber ich sehe, ich würde eine Quelle brauchen. –