public void Listen(CancellationToken token, IEnumerable <Endpoint> endpoints) { ThreadPool.SetMaxThreads(Parallelism, Parallelism); ThreadPool.SetMinThreads(1, 1); _dispatcher = Dispatch <IContext> .CreateDefaultMultithreaded("ResponderThreads", Parallelism); _dispatcher.AddConsumer(_handler.Handle); _dispatcher.Start(); // To use thread pool instead of dispatcher: don't call this and change the code in ListenerCallback var listener = new HttpListener(); Trace.TraceInformation("Binding..."); MainRequestHandler.HttpsAvailable = false; foreach (var endpoint in endpoints) { try { var name = endpoint.Name; var baseUri = $"{endpoint.Protocol}://{endpoint.IPEndpoint}/"; if (endpoint.Protocol == "https") { MainRequestHandler.HttpsAvailable = true; } listener.Prefixes.Add(baseUri); Trace.TraceInformation("Adding listener for '" + name + "' on " + baseUri); } catch (Exception ex) { Trace.Fail("BINDING FAILED! " + ex); return; } } Trace.TraceInformation("Starting..."); try { listener.IgnoreWriteExceptions = false;//true; listener.Start(); } catch (Exception ex) { Trace.Fail("STARTING FAILED! " + ex); return; } Trace.TraceInformation("Started"); while (!token.IsCancellationRequested) { var asctx = listener.BeginGetContext(ListenerCallback, listener); var gotOne = asctx.AsyncWaitHandle.WaitOne(1500, true); // break out of wait loop to allow cancellation to happen. if (gotOne) { Trace.TraceInformation("Incoming message"); } else { OnPeriodicCheck(); } } listener.Stop(); listener.Close(); _dispatcher.Stop(); }