How to cancel HttpListenerContext.AcceptWebSocketAsync?

The best you can do is wrap the listening part in a thread and when you want to cancel execute Abort on the thread.

Be sure to catch the ObjectDisposedException that can happen in the method. Did the same thing for the lower level 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
        }
    }

Hmmm, you get context from HttpListener which is listening to requests (the context does not listen itself, it only wraps requests/responses for you as far as I understand). I guess you should call HttpListener.Stop() Will it do the trick?


Maybe the following solution fits better in your case, which is based on this article.

This will stop listening as soon as the cancellation token is triggert, then you are able to implement the custom logic to cancel the operation. In my case its enough to break the loop, but it can really be anything you want.

    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
        }
    }