У него нет параметра маркера отмены. Также HttpListenerContext не имеет связанных методов (Begin/End) AcceptWebSocket.
Как отменить HttpListenerContext.AcceptWebSocketAsync?
Ответ 1
Возможно, следующее решение подходит лучше в вашем случае, которое основано на этой статье .
Это прекратит прослушивание, как только маркер отмены будет запущен, тогда вы сможете реализовать пользовательскую логику для отмены операции. В моем случае его достаточно, чтобы разбить цикл, но это действительно может быть что угодно.
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
}
}
Ответ 2
Хммм, вы получаете контекст от HttpListener
, который слушает запросы (контекст не прослушивает сам, он только обходит ваши запросы/ответы, насколько я понимаю). Думаю, вам следует позвонить HttpListener.Stop()
Будет ли это трюк?
Ответ 3
Самое лучшее, что вы можете сделать, это обернуть часть прослушивания в потоке и когда вы хотите отменить выполнение Abort в потоке.
Обязательно поймайте 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
}
}
Ответ 4
Все, что я искал, - это способ убедиться, что AcceptWebSocketAsync не будет зависать вечно, договариваясь с враждебным пультом, который блокирует мои потоки прослушивания. Я новичок в Task и ожидаю /async, но это, кажется, делает то, что я хочу:
CancellationTokenSource upgradeTimeout = new CancellationTokenSource(1000);
HttpListenerWebSocketContext webSocketContext = await Task.Run(async () => { return await httpContext.AcceptWebSocketAsync(null); }, upgradeTimeout.Token);
Что-то не так с этим?
Спасибо