【发布时间】:2017-06-18 00:32:15
【问题描述】:
它没有取消令牌参数。 HttpListenerContext 也没有相关的 (Begin/End)AcceptWebSocket 方法。
【问题讨论】:
它没有取消令牌参数。 HttpListenerContext 也没有相关的 (Begin/End)AcceptWebSocket 方法。
【问题讨论】:
也许以下解决方案更适合您的情况,它基于article。
一旦触发取消令牌,这将停止侦听,然后您可以实现自定义逻辑来取消操作。在我的情况下,它足以打破循环,但它真的可以是你想要的任何东西。
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
}
}
【讨论】:
ObjectDisposedException?我一直在寻找避免这种异常的适当方法,但似乎每个人都只是吃了它然后继续前进。
嗯,您从正在侦听请求的HttpListener 获得上下文(上下文不会自行侦听,据我所知,它只为您包装请求/响应)。我想你应该打电话给HttpListener.Stop() 会成功吗?
【讨论】:
HttpListener 的经验和常识^-^ 很高兴知道这是否是正确的方法(我没有使用网络套接字)。
你能做的最好的是将监听部分包装在一个线程中,当你想取消时,在线程上执行 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
}
}
【讨论】:
我一直在寻找一种方法来确保 AcceptWebSocketAsync 不会通过与阻止我的侦听线程的敌对远程进行谈判而永远挂起。我是 Task 和 await/async 的新手,但这似乎符合我的要求:
CancellationTokenSource upgradeTimeout = new CancellationTokenSource(1000);
HttpListenerWebSocketContext webSocketContext = await Task.Run(async () => { return await httpContext.AcceptWebSocketAsync(null); }, upgradeTimeout.Token);
这样做有什么问题吗?
谢谢
【讨论】: