I have a listener:
listener = new HttpListener(); listener.Prefixes.Add(@"http://+:8077/"); listener.Start(); listenerThread = new Thread(HandleRequests); listenerThread.Start();   And I am handling requests:
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 }   I would like to write void Stop() in such a way, that:
ListenerCallback).listener.Stop() (listener.IsListening became false).How could it be write?
EDIT: What do you think about this solution? Is it safe?
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();     } } 
                For completeness, here is what it would look like if you manage your own worker threads:
class HttpServer : IDisposable {     private readonly HttpListener _listener;     private readonly Thread _listenerThread;     private readonly Thread[] _workers;     private readonly ManualResetEvent _stop, _ready;     private Queue<HttpListenerContext> _queue;      public HttpServer(int maxThreads)     {         _workers = new Thread[maxThreads];         _queue = new Queue<HttpListenerContext>();         _stop = new ManualResetEvent(false);         _ready = new ManualResetEvent(false);         _listener = new HttpListener();         _listenerThread = new Thread(HandleRequests);     }      public void Start(int port)     {         _listener.Prefixes.Add(String.Format(@"http://+:{0}/", port));         _listener.Start();         _listenerThread.Start();          for (int i = 0; i < _workers.Length; i++)         {             _workers[i] = new Thread(Worker);             _workers[i].Start();         }     }      public void Dispose()     { Stop(); }      public void Stop()     {         _stop.Set();         _listenerThread.Join();         foreach (Thread worker in _workers)             worker.Join();         _listener.Stop();     }      private void HandleRequests()     {         while (_listener.IsListening)         {             var context = _listener.BeginGetContext(ContextReady, null);              if (0 == WaitHandle.WaitAny(new[] { _stop, context.AsyncWaitHandle }))                 return;         }     }      private void ContextReady(IAsyncResult ar)     {         try         {             lock (_queue)             {                 _queue.Enqueue(_listener.EndGetContext(ar));                 _ready.Set();             }         }         catch { return; }     }      private void Worker()     {         WaitHandle[] wait = new[] { _ready, _stop };         while (0 == WaitHandle.WaitAny(wait))         {             HttpListenerContext context;             lock (_queue)             {                 if (_queue.Count > 0)                     context = _queue.Dequeue();                 else                 {                     _ready.Reset();                     continue;                 }             }              try { ProcessRequest(context); }             catch (Exception e) { Console.Error.WriteLine(e); }         }     }      public event Action<HttpListenerContext> ProcessRequest; } 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With