12

我正在使用HttpListener并使用BeginGetContext来获取我的上下文对象。我想干净地关闭我的 HttpListener 但如果我尝试在侦听器上关闭我会得到一个异常并导致我的程序退出。

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()但该错误从未在 Visual Studio 中显示,我得到的唯一注释是调试输出屏幕中的以下内容:

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

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

应用程序:沙盒 Console.exe
框架版本:v4.0.30319
说明:进程因未处理的异常而终止。
异常信息: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?

4

2 回答 2

16

当您调用 Close 时,最后一次调用上下文,您必须处理可能抛出的对象已处置异常

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.
   }
}
于 2012-11-12T22:05:32.973 回答
0

你可以添加这一行

if (!listener.IsListening) { return; }
HttpListenerContext context = listener.EndGetContext(ctx);
于 2016-06-01T12:42:51.530 回答