异步HttpListener每次接收两次请求

我在c#中实现了一个异步http监听器。

我按照微软提供的教程进行了操作

并发现另一个教程,我愚蠢地没有书签,现在再也找不到了。 这意味着我有一些我不会自己编写的代码,但提供的解释是有道理的,所以我遵循了这一点。

现在我面临两个问题:

首先,我必须在使用Listener.Stop()的每个请求之后重新启动侦听器,然后再次调用StartListening方法,其次,当我这样做时,我会收到两次请求。 请求发送net get两次,但我收到两次。 然而,当我暂停我正在收听的线程大约2秒时,它不会被接收两次。

我很抱歉,如果我的解释很模糊,但我对我的问题的理解也是如此,我不知道是什么导致了它。 由于回调方法是大多数事情发生的地方,我将发布它,请告诉我你是否需要更多的代码。 任何帮助都将很高兴,因为我真的被困在这一个。

public void ListenAsynchronously() { if (listener.Prefixes.Count == 0) foreach (string s in prefixes) listener.Prefixes.Add(s); try { listener.Start(); } catch (Exception e) { Logging.logException(e); } System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Listen)); } private void Listen(object state) { while (listener.IsListening) { listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener); listenForNextRequest.WaitOne(); } } private void ListenerCallback(IAsyncResult ar) { HttpListener httplistener = ar.AsyncState as System.Net.HttpListener; System.Net.HttpListenerContext context = null; int requestNumber = System.Threading.Interlocked.Increment(ref requestCounter); if (httplistener == null) return; try { context = httplistener.EndGetContext(ar); } catch(Exception ex) { return; } finally { listenForNextRequest.Set(); } if (context == null) return; System.Net.HttpListenerRequest request = context.Request; if (request.HasEntityBody) { using (System.IO.StreamReader sr = new System.IO.StreamReader(request.InputStream, request.ContentEncoding)) { string requestData = sr.ReadToEnd(); //Stuff I do with the request happens here } } try { using (System.Net.HttpListenerResponse response = context.Response) { //response stuff happens here } byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString); response.ContentLength64 = buffer.LongLength; response.OutputStream.Write(buffer, 0, buffer.Length); response.Close(); StopListening(); //If I dont set the thread to sleep here, I receive the double requests System.Threading.Thread.Sleep(2500); ListenAsynchronously(); } } catch (Exception e) { } } 

我不确定你为什么要在ListenerCallback()方法中调用StopListening()ListenAsynchronously()Listen()方法正在一个线程中运行,并将继续获取每个下一个传入请求。 如果我写这个,我不会使用HttpListener的实例变量。 在ListenAsynchronously方法中创建一个新方法并将其传递给状态对象,例如,

 public class HttpListenerCallbackState { private readonly HttpListener _listener; private readonly AutoResetEvent _listenForNextRequest; public HttpListenerCallbackState(HttpListener listener) { if (listener == null) throw new ArgumentNullException("listener"); _listener = listener; _listenForNextRequest = new AutoResetEvent(false); } public HttpListener Listener { get { return _listener; } } public AutoResetEvent ListenForNextRequest { get { return _listenForNextRequest; } } } public class HttpRequestHandler { private int requestCounter = 0; private ManualResetEvent stopEvent = new ManualResetEvent(false); public void ListenAsynchronously(IEnumerable prefixes) { HttpListener listener = new HttpListener(); foreach (string s in prefixes) { listener.Prefixes.Add(s); } listener.Start(); HttpListenerCallbackState state = new HttpListenerCallbackState(listener); ThreadPool.QueueUserWorkItem(Listen, state); } public void StopListening() { stopEvent.Set(); } private void Listen(object state) { HttpListenerCallbackState callbackState = (HttpListenerCallbackState)state; while (callbackState.Listener.IsListening) { callbackState.Listener.BeginGetContext(new AsyncCallback(ListenerCallback), callbackState); int n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ListenForNextRequest, stopEvent}); if (n == 1) { // stopEvent was signalled callbackState.Listener.Stop(); break; } } } private void ListenerCallback(IAsyncResult ar) { HttpListenerCallbackState callbackState = (HttpListenerCallbackState)ar.AsyncState; HttpListenerContext context = null; int requestNumber = Interlocked.Increment(ref requestCounter); try { context = callbackState.Listener.EndGetContext(ar); } catch (Exception ex) { return; } finally { callbackState.ListenForNextRequest.Set(); } if (context == null) return; HttpListenerRequest request = context.Request; if (request.HasEntityBody) { using (System.IO.StreamReader sr = new System.IO.StreamReader(request.InputStream, request.ContentEncoding)) { string requestData = sr.ReadToEnd(); //Stuff I do with the request happens here } } try { using (HttpListenerResponse response = context.Response) { //response stuff happens here string responseString = "Ok"; byte[] buffer = Encoding.UTF8.GetBytes(responseString); response.ContentLength64 = buffer.LongLength; response.OutputStream.Write(buffer, 0, buffer.Length); response.Close(); } } catch (Exception e) { } } }