Ho un ascoltatore:Multi-threading con .Net HttpListener
listener = new HttpListener();
listener.Prefixes.Add(@"http://+:8077/");
listener.Start();
listenerThread = new Thread(HandleRequests);
listenerThread.Start();
E sono le richieste di movimentazione:
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
}
vorrei scrivere void Stop()
in modo tale, che:
- Bloccherà fino a quando tutte le richieste attualmente gestite termineranno (cioè attenderà che tutti i thread "facciano un po 'di cose").
- Mentre attende le richieste già avviate, non consente più altre richieste (ad esempio, ritorno all'inizio di
ListenerCallback
). - Dopodiché chiamerà
listener.Stop()
(listener.IsListening
diventato falso).
Come potrebbe essere scrivere?
EDIT: Che cosa ne pensi di questa soluzione? È sicuro?
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();
}
}
Questo non è vero. Se chiami 'listener.Stop()' durante l'esecuzione di 'ListenerCallback' otterrai un'eccezione es. quando si chiama 'EndGetContext' o anche più tardi, quando si utilizza il flusso di output. Naturalmente posso cogliere le eccezioni, ma preferirei non farlo. – prostynick
Nel mio codice uso un flag e non mi riferisco più al listener più dopo aver chiamato stop su di esso, ma chiudendo il listener non si chiudono le connessioni già accettate, solo il listener. –
Non so cosa intendi dicendo "Uso una bandiera". Il problema è che in 'ListenerCallback' sto usando il listener e se un altro thread lo chiude, mentre lo sto usando, finirò con delle eccezioni, che ho menzionato. – prostynick