12

HttpListenerを使用し、BeginGetContextを使用してコンテキストオブジェクトを取得しています。HttpListenerをクリーンにシャットダウンしたいのですが、リスナーでCloseを実行しようとすると、例外が発生し、プログラムが終了します。

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]SandboxConsole.vshost.exe:Managed(v4.0.30319)」がコード0(0x0)で終了しました。

Windowsイベントビューアから実際の実行を取得することができました

アプリケーション:Sandbox 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 に答える