异步检索请求时的C#HTTP侦听器ObjectDisposedException

异步检索请求时的C#HTTP侦听器ObjectDisposedException,c#,asynchronous,server,httplistener,C#,Asynchronous,Server,Httplistener,我是初学者,请容忍我 我一直在尝试编写一个非常简单的C#HTTP侦听器,它可以异步处理客户端请求 为此,我使用了官方Microsoft文档中的以下示例代码: 即使我使用完全相同的代码,我仍然会得到一个ObjectDisposed异常。我只能通过在主线程中手动等待几毫秒来修复它,但这是我想要修复的一个糟糕的解决方案,因为它显然会极大地降低速度 似乎主线程在工作完成之前没有等待并关闭侦听器,导致对象被过早地处理。我想这就是为什么手动等待可以修复它。但是为什么WaitOne()方法不等待呢 为了减少

我是初学者,请容忍我

我一直在尝试编写一个非常简单的C#HTTP侦听器,它可以异步处理客户端请求

为此,我使用了官方Microsoft文档中的以下示例代码:

即使我使用完全相同的代码,我仍然会得到一个ObjectDisposed异常。我只能通过在主线程中手动等待几毫秒来修复它,但这是我想要修复的一个糟糕的解决方案,因为它显然会极大地降低速度

似乎主线程在工作完成之前没有等待并关闭侦听器,导致对象被过早地处理。我想这就是为什么手动等待可以修复它。但是为什么WaitOne()方法不等待呢

为了减少个人错误,我使代码与示例几乎相同,我只手动添加前缀

听众:

public static void NonblockingListener()
{
    HttpListener listener = new HttpListener();
    listener.Prefixes.Add("http://localhost:8080/test/");
    listener.Start();

    IAsyncResult result = listener.BeginGetContext(new AsyncCallback(ListenerCallback),listener);

    Console.WriteLine("Waiting for request to be processed asyncronously.");
    result.AsyncWaitHandle.WaitOne();
    Console.WriteLine("Request processed asyncronously.");

    // It will only work if I add this: System.Threading.Thread.Sleep(200);
    listener.Close();
}
回调方法:

public static void ListenerCallback(IAsyncResult result)
{
    HttpListener listener = (HttpListener) result.AsyncState;  

    // It throws the exception at this line
    HttpListenerContext context = listener.EndGetContext(result);

    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;

    string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
    response.ContentLength64 = buffer.Length;
    System.IO.Stream output = response.OutputStream;
    output.Write(buffer,0,buffer.Length);
    output.Close();
}
我是愚蠢还是认为示例代码有问题是正确的? 那会很奇怪,但我真的不知道我做错了什么

如果有人可以复制相同的示例代码并尝试运行它,那就太好了


我需要做些什么才能让它正常工作?

我自己在痛苦的几个小时后找到了答案,我会在这里发布一个答案,以防有人有同样的问题。问题是我一直关闭并重新创建侦听器,而不是在下一个请求中重用它。这是我从MSDN示例代码页复制的错误。它在检索客户端请求后立即关闭侦听器,导致错误,因为回调方法无法再访问关闭的侦听器来处理仍在运行的请求

解决方案是删除主函数中的循环,而是在其周围放置一个无限循环:

IAsyncResult result = listener.BeginGetContext(newAsyncCallback(ListenerCallback),listener);
result.AsyncWaitHandle.WaitOne();

这似乎很明显,但我想我只是把MSDN视为理所当然,这显然是一个错误。

result.AsyncWaitHandle.WaitOne()
将返回一次
listener.EndGetContext(结果)返回-即在写入输出之前。请尝试在
之前使用
.Stop()
.Close()
-
.Stop()
是一种更为优雅的关机方式,我希望它会等到所有请求都处理完毕。此外,当MSDN上的一个示例出现问题时,不要太惊讶——其中一些问题值得怀疑quality@canton7如果我将
.Close()
替换为
.Stop()
或在关闭前停止侦听器,它会在此行抛出一个无效句柄异常:
output.Write(buffer,0,buffer.Length)。有什么想法吗?
IAsyncResult result = listener.BeginGetContext(newAsyncCallback(ListenerCallback),listener);
result.AsyncWaitHandle.WaitOne();