| 

.NET C# Java Javascript Exception

4
Ich experimentiere derzeit mit der System.Net.HttpListener-Klasse, und habe dabei ein Problem, bei dem ich nicht weiterkomme.

Variante 1: Ich rufe die GetContext-Methode auf und warte, bis ein Request hereinkommt. Das funktioniert auch wunderbar, und der Request wird verarbeitet. Wenn allerdings während der Verarbeitung ein zweiter Request hereinkommt, erhalte ich eine Exception am Client, dass der Zielcomputer die Verbindung verweigert hat.

Frage 1: Warum?
Frage 2: Meine Vermutung ist, dass Requests nicht gequeued werden, so dass kein Request angenommen wird, wenn die Methode GetContext nicht aktiv wartet. So lange also der vorherige Request noch verarbeitet wird, werden keine neuen Requests mehr angenommen. Richtig?

Variante 2: Nun habe ich mir gedacht, dass das Problem ja relativ einfach aus der Welt zu schaffen sein müsste, indem man die Verarbeitung des Requests einfach asynchron macht. Also wieder GetContext aufgerufen, dieses Mal aber, indem ich den Handler an einen neuen Task aus der TPL hänge, diesen starte, und ihm das HttpListenerContext-Objekt übergebe.

Nun sollte - für mein Verständnis - der Handler in einem eigenen Thread laufen, und der Hauptthread sofort zu GetContext zurückkehren, so dass neue Requests angenommen werden können. Offensichtlich tut es das aber nicht, denn das Ergebnis ist das Gleiche wie bei Variante 1.

Frage: Warum?

Variante 3: Ich verwende BeginGetContext statt GetContext. Dann habe ich aber das Problem, dass sich meine Anwendung sofort verabschiedet - logisch, denn das Warten geschieht ja nun in einem Hintergrundthread. Nutze ich nun aber wiederum das WaitHandler des AsyncResults, blockt der Hauptthread wieder, bis der eingegangene Request verarbeitet wurde, und nimmt keine weiteren Requests mehr entgegen.

Frage: Wie löse ich das richtig ;-)?

Und last but not least: Wo liegt mein prinzipieller Denkfehler, beziehungsweise wie muss ich vorgehen, damit ich mehrere Requests gleichzeitig verarbeiten kann - auch wenn das Verarbeiten unter Umständen mal etwas länger dauert?
News:
30.03.2011
Golo Roden 2,7k 3 9
2 Antworten
3
zu spät, ich kann's im moment auch nicht testen - aber ich meine das sollte ungefähr so aussehen:
public class listener {
System.Threading.AutoResetEvent are = new System.Threading.AutoResetEvent(false);
HttpListener item = new HttpListener();
public void run(){
item.Start();
do {System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(listen));
are.WaitOne();} while (1 == 1);

}
private void listen(object state){
item.BeginGetContext(null, null);
are.Set();}
}
30.03.2011
wurzelchen 289 5
Danke, so ungefähr funktioniert's auch - der entscheidende Punkt ist halt, dass man in der listen-Methode wieder BeginGetContext aufruft. Allerdings muss man die Dinger erstmalig trotzdem in einer Schleife aufrufen, sonst hat man halt nur einen einzigen Thread, und wenn der beschäftigt ist, müssen alle anstehenden Requests warten. Wie gesagt, einfach um das initiale BeginGetContext eine Schleife drum, nach Wunsch entsprechend viele Threads erzeugen, und gut ist ...
Golo Roden 30.03.2011
0
Die Frage hat sich erledigt - man sollte seinen Code einfach manchmal genauer lesen, und auf die richtige Reihenfolge von bestimmten Dingen achten. Zum Beispiel, dass man den HttpListener auch korrekt loslaufen lässt, BEVOR man mit mehreren Connections gleichzeitig ankommt ...

Ich habe es jetzt folgendermaßen gelöst: Der Hauptthread ruft in einer Schleife 50 Mal BeginGetContext auf, und sobald ein solcher Thread abgearbeitet wurde, ruft er erneut BeginGetContext auf - der Thread stellt sich sozusagen selbst wieder zur Verfügung ...

Ist vielleicht nicht die schönste Lösung, aber für den Spike, an dem ich gerade bin, reicht es.
30.03.2011
Golo Roden 2,7k 3 9

Stelle deine Httplistener-Frage jetzt!