Ich habe einen Hörer:Multi-Threading mit .Net Httplistener
listener = new HttpListener();
listener.Prefixes.Add(@"http://+:8077/");
listener.Start();
listenerThread = new Thread(HandleRequests);
listenerThread.Start();
Und ich bin Umgang mit Anfragen:
private void HandleRequests()
{
while (listener.IsListening)
{
var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
context.AsyncWaitHandle.WaitOne();
}
}
private void ListenerCallback(IAsyncResult ar)
{
var listener = ar.AsyncState as HttpListener;
var context = listener.EndGetContext(ar);
//do some stuff
}
Ich möchte void Stop()
so schreiben, dass:
- Es wird blockiert, bis alle aktuell bearbeiteten Anfragen enden (dh auf alle Threads warten, "um etwas zu tun").
- Während auf bereits gestartete Anfragen gewartet wird, werden keine weiteren Anfragen mehr erlaubt (zB Rückkehr zu Beginn von
ListenerCallback
). - Danach wird es anrufen
listener.Stop()
(listener.IsListening
wurde falsch).
Wie könnte es schreiben?
EDIT: Was denken Sie über diese Lösung? Ist es sicher?
public void Stop()
{
lock (this)
{
isStopping = true;
}
resetEvent.WaitOne(); //initially set to true
listener.Stop();
}
private void ListenerCallback(IAsyncResult ar)
{
lock (this)
{
if (isStopping)
return;
resetEvent.Reset();
numberOfRequests++;
}
var listener = ar.AsyncState as HttpListener;
var context = listener.EndGetContext(ar);
//do some stuff
lock (this)
{
if (--numberOfRequests == 0)
resetEvent.Set();
}
}
Dies ist nicht wahr. Wenn Sie 'listener.Stop()' während der Ausführung von 'ListenerCallback' aufrufen, erhalten Sie eine Ausnahme, z. beim Aufruf von 'EndGetContext' oder sogar später, wenn Ausgabestrom verwendet wird. Ich kann die Ausnahmen natürlich abfangen, aber das würde ich lieber nicht tun. – prostynick
In meinem Code benutze ich ein Flag und nicht mehr auf den Listener, nachdem ich Stop aufgerufen habe, aber das Schließen des Listeners schließt nicht die bereits akzeptierten Verbindungen, nur den Listener. –
Ich weiß nicht, was meinst du mit "Ich benutze eine Flagge". Das Problem ist, dass ich in "ListenerCallback" Listener verwende und wenn ein anderer Thread es schließt, während ich es benutze, werde ich mit Ausnahmen enden, die ich erwähnt habe. – prostynick