none
Asynchronen Aufruf in Session speichern RRS feed

  • Frage

  • Hallo zusammen,

    mir fällt leider kein besserer Titel ein ;)

    Ich habe eine Webseite, die asynchron Daten von einem entfernten (nur über VPN erreichbaren) WebService (ab jetzt nenn ich den nur "E") holen und anzeigen muss. Dieser WebService kann unter Umständen jede Minute einen anderen Wert zurückliefern, so dass nicht (oder nur kurz) gecached werden soll. Da die Ausführung von E aber auch recht lange dauern kann, soll das asynchron geschehen. Also muss ich den Umweg über einen "lokalen" WebService (=gleiche Domain) gehen.

    Noch bevor ich die Webseite anzeige, kenne ich schon die Parameter für E. Daher kam ich auf die Idee, die Anfrage an E bereits zu starten, bevor die Seite überhaupt angezeigt wird. Innerhalb der Seite wird dann per AJAX der "lokale" WebService (L) abgefragt. Dort wird wiederum gewartet, bis die Daten von E angekommen sind und diese dann zurückgegeben. Wenn man Glück hat, sind die Daten auch schon da...

    Zum Abholen der Daten hab ich eine Klasse geschrieben. Diese wird mit entsprechenden Daten instanziert, holt sich asynchron die Daten von E und wird dann auch gleich in die Session-Auflistung eingefügt. Da jede Anfrage (auch wenn die Parameter gleich sind) zu einem anderen Ergebnis führt, sind das nicht unbedingt wenige Objekte innerhalb meiner Session. Daher wird, sobald der Wert dann angefragt wird, das Objekt auch wieder aus der Session-Auflistung entfernt.

    Jetzt ist es so, dass (wenn man die Script-Ausführung abbricht, z.B. durch klick auf einen Link), aber ein Objekt auch "nie" abgefragt werden. Damit das nicht zu zuviel Objekten in der Auflistung führt, hab ich innerhalb des Konstruktors ein System.Threading.Timer instanziert, mit dem nach Ablauf von einer Minute das Objekt aus der Session-Auflistung entfernt wird.

    Grundsätzlich funktioniert das. Ich hab nur Bedenken bei Last. Mein erst Frage ist daher, ob ich hier zu kompliziert denke und es einen viel einfacheren Weg gibt? Push vom Webserver(IIS 7.5) zur Webseite wird es wohl noch nicht geben, oder?

    Ich kann dies gerne noch umstellen auf Application-Level, und auch die Auflistung selbst kann ich gerne selbst verwalten (wenn es was bringt). Ich hätte hier aber ein ähnliches Problem. An welcher Stelle soll ich das Objekt (zur Verwaltung des Ganzen) instanzieren? Bin mit Application_Start nicht wirklich zum Ziel gekommen. Und wie kann man auf eine (eigene) Eigenschaft/Funktion innerhalb der global.asax zugreifen (von einem WebService oder einer aspx-Seite aus).

    Gibt es überhaupt Objekte auf Applikatons-Ebene die über alle Sessions hinweg erhalten bleiben? Das wäre mir grundsätzlich lieber als eine Session (da diese nicht InProc sein soll System.Threading.Timer ist nicht Serializable).

    Ich kenne die Application-Auflistung, sträube mich aber - aus mir selbst unbekannten Gründen - ein wenig davor. Oder ist das der Weg?

    Ich hoffe, es ist halbwegs verständlich, was ich vorhabe ;) Nochmal in Kurzform:

    Request an Webseite
        -> Asynchroner Aufruf von entferntem WebService
        -> Response der Webseite

    AJAX-Request an Webseite
        -> Warten auf Antwort aus asynchronem Aufruf von entferntem WebService, falls noch nicht fertig
        -> Response mit dieser Antwort

    Schonmal danke für's lesen.

    Gruß, Michel

    Dienstag, 5. April 2011 15:12

Antworten

  • Hallo Michel,
    Gibt es überhaupt Objekte auf Applikatons-Ebene die über alle Sessions hinweg erhalten bleiben? Das wäre mir grundsätzlich lieber als eine Session (da diese nicht InProc sein soll System.Threading.Timer ist nicht Serializable).

    Ich kenne die Application-Auflistung, sträube mich aber - aus mir selbst unbekannten Gründen - ein wenig davor. Oder ist das der Weg?

    wenn Du sessionübergreifen Daten zwischenspeichern willst, kannst Du

    a) eine Applicationvariable nehmen:
        Application( "MeineApplicationVariable" ) = <DeinObjekt>

    b) eine statische Property verwenden:

        Class Xyz

            Private Shared _Irgendwas As ...

            Public Shared Property Irgendwas As ...
                ...
            End Property

        End Class

        Ansprechen kannst Du die mit:

        Xyz.Irgendwas = ...

        Allerdings musst Du zwingend darauf achten, dass die Zugriffe synchronisiert sind, da Request2 sonst bspw. dem aktuell lesenden Request1 die Daten unterm Hintern hinweg ändert.

    c) die Daten in eine Datenbank o.ä. zwischenspeichern

    ---

    Es kommt primär darauf an, ob die Daten überhaupt requestbezogen bzw. benutzer/sessionbezogen sind.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    • Als Antwort markiert M-Michel Dienstag, 5. April 2011 16:00
    Dienstag, 5. April 2011 15:53
    Moderator

Alle Antworten

  • Hallo Michel,
    Gibt es überhaupt Objekte auf Applikatons-Ebene die über alle Sessions hinweg erhalten bleiben? Das wäre mir grundsätzlich lieber als eine Session (da diese nicht InProc sein soll System.Threading.Timer ist nicht Serializable).

    Ich kenne die Application-Auflistung, sträube mich aber - aus mir selbst unbekannten Gründen - ein wenig davor. Oder ist das der Weg?

    wenn Du sessionübergreifen Daten zwischenspeichern willst, kannst Du

    a) eine Applicationvariable nehmen:
        Application( "MeineApplicationVariable" ) = <DeinObjekt>

    b) eine statische Property verwenden:

        Class Xyz

            Private Shared _Irgendwas As ...

            Public Shared Property Irgendwas As ...
                ...
            End Property

        End Class

        Ansprechen kannst Du die mit:

        Xyz.Irgendwas = ...

        Allerdings musst Du zwingend darauf achten, dass die Zugriffe synchronisiert sind, da Request2 sonst bspw. dem aktuell lesenden Request1 die Daten unterm Hintern hinweg ändert.

    c) die Daten in eine Datenbank o.ä. zwischenspeichern

    ---

    Es kommt primär darauf an, ob die Daten überhaupt requestbezogen bzw. benutzer/sessionbezogen sind.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    • Als Antwort markiert M-Michel Dienstag, 5. April 2011 16:00
    Dienstag, 5. April 2011 15:53
    Moderator
  • Hallo Stefan,

    Antwort b hat es mir angetan :-)
    Die Daten sind zwar sessionbezogen, aber das macht dann eine Manager-Klasse.

    So sieht das schon viel besser aus. Vielen Dank.

    Gruß, Michel

    Dienstag, 5. April 2011 16:00