干净地中断HttpListener的BeginGetContext方法

我正在使用HttpListener并使用BeginGetContext来获取我的上下文对象。 我想干净地关闭我的HttpListener但是如果我尝试在侦听器上执行Close操作,我会得到一个exception,它会导致我的程序退出。

using System; using System.Net; namespace Sandbox_Console { class Program { public static void Main() { if (!HttpListener.IsSupported) { Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class."); return; } // Create a listener. HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://vwdev.vw.local:8081/BitsTest/"); listener.Start(); Console.WriteLine("Listening..."); listener.BeginGetContext(Context, listener); Console.ReadLine(); listener.Close(); //Exception on this line, but not shown in Visual Studio Console.WriteLine("Stopped Listening..."); //This line is never reached. Console.ReadLine(); } static void Context(IAsyncResult result) { HttpListener listener = (HttpListener)result.AsyncState; HttpListenerContext context = listener.EndGetContext(result); context.Response.Close(); listener.BeginGetContext(Context, listener); } } } 

该程序在listener.Close()上引发exception,但是错误永远不会在Visual Studio中显示,我得到的唯一注释是Debug输出屏幕中的以下内容:

System.dll中发生了’System.ObjectDisposedException’类型的第一次机会exception
程序'[2568] Sandbox Console.vshost.exe:Managed(v4.0.30319)’已退出,代码为0(0x0)。

我能够从Windows事件查看器中获得真正的执行

应用程序:Sandbox Console.exe
框架版本:v4.0.30319
描述:由于未处理的exception,进程终止。
exception信息:System.ObjectDisposedException
堆:
   在System.Net.HttpListener.EndGetContext(System.IAsyncResult)
   在Sandbox_Console.Program.Context(System.IAsyncResult)
   在System.Net.LazyAsyncResult.Complete(IntPtr)
   在System.Net.ListenerAsyncResult.WaitCallback(UInt32,UInt32,System.Threading.NativeOverlapped *)
   在System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32,UInt32,System.Threading.NativeOverlapped *)

我需要做什么才能干净地关闭我的HttpListener?

当您调用Close时,上次调用Context,您必须处理可能被抛出的对象处置exception

 static void Context(IAsyncResult result) { HttpListener listener = (HttpListener)result.AsyncState; try { //If we are not listening this line throws a ObjectDisposedException. HttpListenerContext context = listener.EndGetContext(result); context.Response.Close(); listener.BeginGetContext(Context, listener); } catch (ObjectDisposedException) { //Intentionally not doing anything with the exception. } } 

你可以添加这一行

 if (!listener.IsListening) { return; } HttpListenerContext context = listener.EndGetContext(ctx);