停止并重新启动HttpListener?

时间:2013-06-05 17:37:45

标签: c# multithreading httplistener

我正在处理一个HttpListener的应用。我的目标是让用户根据他们的选择关闭和打开监听器。我把Listener放在一个新线程中,我遇到了一个中止该线程的问题。我在某处读到,如果您尝试中止处于非托管上下文中的线程,则只要它重新进入托管上下文,ThreadAbortException就会被触发。似乎HttpListener的GetContext()方法是不受管理的,因为当我尝试中止线程时,在我针对我的应用程序发出Web请求之前没有任何事情发生。然后线程退出。问题是当我试图杀死线程时,我可能稍后在同一个端口上再次启动线程,并且HttpListenerException说明前缀已经注册。

如何杀死交叉线程HttpListener?是否存在允许线程中止的GetContext()的托管替代方法?我可以以非托管代码停止的方式中止线程吗?

4 个答案:

答案 0 :(得分:3)

如下:

public class XListener
{
    HttpListener listener;

    public XListener(string prefix)
    {
        listener = new HttpListener();
        listener.Prefixes.Add(prefix);
    }

    public void StartListen()
    {
        if (!listener.IsListening)
        {
            listener.Start();

            Task.Factory.StartNew(async () =>
            {
                while (true) await Listen(listener);
            }, TaskCreationOptions.LongRunning);

            Console.WriteLine("Listener started");
        }
    }

    public void StopListen()
    {
        if (listener.IsListening)
        {
            listener.Stop();
            Console.WriteLine("Listener stopped");
        }
    }

    private async Task Listen(HttpListener l)
    {
        try
        {
            var ctx = await l.GetContextAsync();

            var text = "Hello World";
            var buffer = Encoding.UTF8.GetBytes(text);

            using (var response = ctx.Response)
            {
                ctx.Response.ContentLength64 = buffer.Length;
                ctx.Response.OutputStream.Write(buffer, 0, buffer.Length);
            }
        }
        catch (HttpListenerException)
        {
            Console.WriteLine("screw you guys, I'm going home!");
        }
    }
}

用法:

var x = new XListener("http://locahost:8080");

x.StartListen();
Thread.Sleep(500); // test purpose only

x.StopListen();
Thread.Sleep(500); // test purpose only

x.StartListen();

/* OUTPUT:
=> Listener started
=> Listener stopped
=> screw you guys, I'm going home!
=> Listener started */

答案 1 :(得分:1)

你需要通知线程调用HttpListener.Stop()并通过调用Thread.Join()来等待线程完成

答案 2 :(得分:0)

您需要做的就是在侦听器上调用stop。由于您的侦听器线程在GetContext上被阻止,因此您需要在另一个线程上执行此操作。 IIRC这将导致GetContext抛出,因此您将需要处理该异常并进行清理。调用Thread.Abort应该是你的最后手段,并且不会导致听众停止收听,直到它被垃圾收集为止。

答案 3 :(得分:0)

typedef struct sBRIDGE_TREE
{
  [...]
}
BRIDGE_TREE;

void SetBridgeIdentifier (BRIDGE_TREE* bridgeTree, unsigned short settablePriorityComponent, unsigned short treeIndex, const unsigned char address[6])
{
  SetPriorityAndMstid(bridgeTree, settablePriorityComponent, treeIndex);
  BridgeIdentifier.SetAddress(bridgeTree, address);
  UpdateBridgePriorityFromBridgeIdentifier(bridgeTree);
}

void SetPriorityAndMstid(BRIDGE_TREE* bridgeTree, unsigned short settablePriorityComponent, unsigned short treeIndex)
{
  [...]
}

void BridgeIdentifier.SetAddress(BRIDGE_TREE* bridgeTree, const unsigned char address[6])
{
  [...]
}

void UpdateBridgePriorityFromBridgeIdentifier(BRIDGE_TREE* bridgeTree)
{
  [...]
}

相关问题