Benutzer mit den meisten Antworten
Webservice: Multitasking umgehen?

Frage
-
Frage : Wie kann ich meinen Webservice dazu bringen, jede Anfrage komplett abzuarbeiten, bevor er mit der nächsten beginnt?
Hintergrund : typisches keine-grüne-Wiese-Problem - eine vom Webservice verwendete VB6-DLL ist nicht multitaskingfähig. Ich habe bereits eine Lösung, die darin besteht, die VB6-DLL als ActiveX-EXE laufen zu lassen, was aber unter anderem zu einem mieserablen Laufzeitverhalten führt (Faktor 3, Antwortzeiten z.T. im zweistelligen Sekundenbereich). Die DLL multitaskingfähig zu machen wäre natürlich prinzipiell auch möglich, es handelt sich aber um einen wahren Moloch von ca. 200.000 Zeilen Code der zudem in einer anderen Umgebung seit langem in Betrieb ist, was eine Umstellung ziemlich aufwändig und auch etwas riskant erscheinen lässt. Ich suche also nach einer Alternative/Interimslösung, die schnell umzusetzen ist und das Laufzeitproblem löst. Die Silverlight-Anwendung wird gerade in Betrieb genommen.
Freitag, 7. Mai 2010 10:08
Antworten
Alle Antworten
-
Hi,
Frage : Wie kann ich meinen Webservice dazu bringen, jede Anfrage komplett abzuarbeiten, bevor er mit der nächsten beginnt?
Du meinst einen ASP.NET Webservice? Oder den Aufruf eines beliebigen Webservice aus Silverlight heraus?
Grundsätzlich hast Du ja das Problem, dass es beliebig viele Clients sein können. Daher erstmal die Frage, was denn beim zweiten Client passieren soll, wenn ein anderer Client bereits einen Aufruf an den Webservice gemacht hat. Gar nichts? Warten, bis der andere Aufruf durch ist? Fehlermeldung? ...?
"Warten" wäre wohl die schlechteste Option, da sich die Aufrufe dann bis ins unendliche aufstauen können. Eine Meldung könntest Du relativ einfach durch eine statische Property (oder Applicationvariable) erreichen. Beim ersten Aufruf wird die statische Property (bspw. <Class>.Running = True) gesetzt. In der Webservicemethode wird diese Property abgefragt und ggfs. eine Exception geworfen (oder eine Meldung zurückgegeben). Wenn der Aufruf des Webservice durch ist, wird die Eigenschaft zurückgesetzt (<Class>.Running = False)
Das geht natürlich auch anders aber für einfache Zwecke dürfte obiges ausreichen.
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 CommunityFreitag, 7. Mai 2010 10:59 -
Hallo Stefan,
entschuldigung, hätte ich erwähnen können: der Webservice ist ein von mir im Rahmen meines Silverlight-Projekts erstellter WCF-Dienst - nur um den geht's.
Der zweite Client soll innerhalb des Webservices warten bis der erste durch ist - verbunden mit einem Timeout-Mechanismus. Deine clientseitige Version hab ich mir auch schon überlegt, ich würde es aber eigentlich lieber serverseitig lösen, da eine UI-Meldung der Art "Versuchen Sie es später noch einmal" nicht sinnvoll wäre zumindest nicht gleich beim ersten Anlauf, ich müsste den WS-Aufruf direkt & automatisiert wiederholen, bis ich durchkomme - entweder sofort (unnötiges "Trommelfeuer") oder in festen Intervallen (recht zufällige Abarbeitungsfolge mehrerer wartender Clients, unnötige Leerlaufzeiten). Ich weiß natürlich nicht, ob es da eine elegante Lösung gibt - aber deswegen frag ich ja :-)
Danke!
Freitag, 7. Mai 2010 11:39 -
Hi,
Deine clientseitige Version hab ich mir auch schon überlegt, ich würde es aber eigentlich lieber serverseitig lösen, da eine UI-Meldung der Art "Versuchen Sie es später noch einmal" nicht sinnvoll wäre zumindest nicht gleich beim ersten Anlauf,
meine Version war serverseitig, nicht clientseitig gedacht. Im Client macht es auch keinerlei Sinn, da der eine Client vom anderen nichts weiß.ich müsste den WS-Aufruf direkt & automatisiert wiederholen, bis ich durchkomme - entweder sofort (unnötiges "Trommelfeuer") oder in festen Intervallen (recht zufällige Abarbeitungsfolge mehrerer wartender Clients, unnötige Leerlaufzeiten). Ich weiß natürlich nicht, ob es da eine elegante Lösung gibt - aber deswegen frag ich ja :-)
Da bleibt dir eigentlich nur eine sowohl client- als auch serverseitige Lösung.
Den serverseitigen Kram hatte ich oben ja schon beschrieben. Du müsstest dann bspw. anhand der Exception, die beim Client wieder ankommt, erkennen, dass das deine "Bin noch am arbeiten" Meldung ist und dann über einen Timer den Aufruf periodisch wiederholen.
Ob es da was eleganteres gibt, weiß ich nicht. Aber da ein solches Verhalten IMHO nicht wirklich was gewöhnliches ist, würde ich mal sagen: Nö :)
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 CommunityFreitag, 7. Mai 2010 12:02 -
Hallo Stefan,
"meine Version war serverseitig, nicht clientseitig gedacht": schon klar, vielleicht hab ich mich falsch ausgedrückt, sorry. Ich weiß genau was Du meinst, hab eine Lösung wie von Dir beschrieben an anderer Stelle schon drin.
Dass das Aufbauen und Abarbeiten der Warteschlange rein serverseitig machbar ist, glaub ich eigentlich schon. Holzhammermethode (bitte nicht schlagen, ich werd's so nicht machen, nur zur Veranschaulichung!!):
Public Class Service1
...
Shared iAmBusy as Boolean
Public Sub DoSomething()
While iAmBusy
Wend
iAmBusy=True
... (Verarbeitung)
iAmBusy=False
End Sub
Dieses While-iAmBusy-Wend legt vermutlich sinnlos den Prozessor lahm, mir fiele da nur ein Timer ein, womit ich aber erstmal aus der Routine (hier: DoSomething) draußen bin und somit die Input-Parameter retten muß. Insgesamt schien mir das auf den ersten Blick zwar machbar, aber irgendwie zu umständlich. Schön wäre halt irgendein "eins-nach-dem-anderen"-Hauptschalter auf übergeordneter Ebene... und wenn es den nicht gibt, würde ich mich trotzdem über einen gewieften codeseitigen Ansatz freuen...
Grüße,
Thilo
Freitag, 7. Mai 2010 13:10