如何取消HttpListenerContext.AcceptWebSocketAsync?

时间:2017-02-01 09:59:20

标签: c# .net http websocket

它没有取消令牌参数。 HttpListenerContext也没有相关的(Begin / End)AcceptWebSocket方法。

4 个答案:

答案 0 :(得分:4)

以下解决方案可能更适合您的情况,该情况基于此article

一旦取消令牌为triggert,这将停止侦听,然后您就可以实现自定义逻辑来取消操作。在我的情况下,它足以打破循环,但它确实可以是你想要的任何东西。

    public void Stop()
    {
        this.Status = ServerStatus.Stopping;

        this.listener.Stop();
        this.cancellationTokenSource.Cancel();

        this.Status = ServerStatus.Stopped;
    }

    private async void ListenForConnections(CancellationToken cancellationToken)
    {
        try
        {
            while (this.Status == ServerStatus.Running)
            {
                var socketTask = this.listener.AcceptSocketAsync();

                var tcs = new TaskCompletionSource<bool>();
                using (cancellationToken.Register(s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
                {
                    if (socketTask != await Task.WhenAny(socketTask, tcs.Task).ConfigureAwait(false))
                        break;
                }

                var context = new TcpContext(socketTask.Result);

                this.OnConnectionReceived(context);
            }
        }
        catch (ObjectDisposedException)
        {
            // Closed
        }
    }

答案 1 :(得分:2)

嗯,你从HttpListener获得正在监听请求的上下文(上下文不会自己监听,它只根据我的理解为你包装请求/响应)。我猜你应该打电话给HttpListener.Stop()它会不会这样做?

答案 2 :(得分:1)

你可以做的最好的事情是将听力部分包装在一个线程中,当你想取消线程上的执行中止时。

确保捕获可能在方法中发生的ObjectDisposedException。 为较低级别的TcpListener做了同样的事情。

    public void Stop()
    {
        this.Status = ServerStatus.Stopping;
        this.listener.Stop();

        this.listeningThread.Abort();

        this.Status = ServerStatus.Stopped;
    }

    /// <summary>
    ///     Listens for connections.
    /// </summary>
    private async void ListenForConnections()
    {
        try
        {
            while (this.Status == ServerStatus.Running)
            {
                var socket = await this.listener.AcceptSocketAsync();
                var context = new TcpContext(socket);

                this.OnConnectionReceived(context);
            }
        }
        catch (ObjectDisposedException)
        {
            // Closed
        }
    }

答案 3 :(得分:0)

我一直在寻找的一种方法是通过与阻止我的侦听线程的敌对遥控器进行协商来确保AcceptWebSocketAsync不会永远挂掉。我是Task和await / async的新手,但这似乎可以满足我的要求:

CancellationTokenSource upgradeTimeout = new CancellationTokenSource(1000);
HttpListenerWebSocketContext webSocketContext = await Task.Run(async () => { return await httpContext.AcceptWebSocketAsync(null); }, upgradeTimeout.Token);

这样做有什么问题吗?

谢谢