1

私は C# で小さな SMS サーバーを開発しており、SMS オブジェクト (ユーザー名、メッセージなど) に送信された要求を処理する非同期リスナーを作成したいと考えています。非同期リスナーをクラス ライブラリとして作成したいと考えています。コードは次のとおりです。

using System;
using System.Net;
using System.Threading;

namespace AListener
{
    public class CAListener
    {
        public CAListener()
        {
            Thread listener = new Thread(new ParameterizedThreadStart(RequestListener));
            listener.Start(new string[] { "http://*:11600/" });
        }

        private ManualResetEvent stopListener = new ManualResetEvent(false);
        private object lockListener = new object();
        private bool newRequest = false;

        public void StopListener()
        {
            stopListener.Set();
        }

        public void RequestListener(object parameter)
        {
            string[] prefixes = parameter as string[];

            HttpListener listener = new HttpListener();

            foreach (string prefix in prefixes)
            {
                listener.Prefixes.Add(prefix);
            }

            listener.Start();

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

            while (!stopListener.WaitOne(10))
            {
                lock (lockListener)
                {
                    if (newRequest)
                    {
                        result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);

                        newRequest = false;
                    }
                }

                result.AsyncWaitHandle.WaitOne(10);
            }

            listener.Close();
        }

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

            // Call EndGetContext to complete the asynchronous operation.
            HttpListenerContext context = listener.EndGetContext(result);

            HttpListenerRequest request = context.Request;

            // Obtain a response object.
            HttpListenerResponse response = context.Response;

            // Construct a response. 
            string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);

            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;

            System.IO.Stream output = response.OutputStream;

            output.Write(buffer, 0, buffer.Length);

            // You must close the output stream.
            output.Close();

            lock (lockListener)
            {
                newRequest = true;
            }
        }
    }
}

AListener オブジェクトを取得する UI フォームがあり、ここではすべて問題ありません。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AListener;

namespace ZNSMS
{
    public partial class ZNSMSServer : Form
    {
        public ZNSMSServer()
        {
            InitializeComponent();
        }

        CAListener ca = null;

        private void button1_Click(object sender, EventArgs e)
        {
            ca.StopListener();
        }

        private void ZNSMSServer_Load(object sender, EventArgs e)
        {
            ca = new CAListener();
        }
    }
}

しかし、ボタンを押すと (リスナーを停止したいだけです)、何らかの理由listener.Stop()でメインの UI Form が強制終了されますZNSMSServer。コメントlistener.Stop()すると機能していますが、それは適切な方法ではないと思いlistener.Stop()ます。また、呼び出しが呼び出し元オブジェクトに影響を与える理由 (この場合は Close?) を理解できません - この場合はZNSMSServer.

以前にこの種の問題に対処したことがある人がいれば、本当に感謝しています。前もって感謝します。

4

0 に答える 0