2

在我的 .NET Core 控制台应用程序中,我使用 ClientWebSocket 对象的集合来接收一些数据。当出现问题并发生异常时,我想关闭所有 websocket。

我试图这样做:

foreach (var socket in _sockets)
{
    if (socket.State == WebSocketState.Open || socket.State == WebSocketState.Connecting)
    {
        socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait();
    }
}

但万一socket.State == WebSocketState.Connecting有例外:

System.AggregateException: '发生一个或多个错误。(对于此操作,WebSocket 处于无效状态(“正在连接”)。有效状态为:“打开、关闭接收、关闭发送”)

我知道我可以使用socket.Abort()forWebSocketState.Connecting和 for WebSocketState.Open

问题是这是否是关闭连接的最合适方法 - 使用CloseAsyncforWebSocketState.OpenAbortfor WebSocketState.Connecting

4

1 回答 1

1

简单地说,你不能关闭没有打开的东西。方法SendAsync, ReceiveAsync, CloseAsync,CloseOutputAsync总是在采取任何其他行动之前检查套接字的状态。如果状态不是“已连接”,它们会抛出异常。

以下状态被视为“未连接”:

  • WebSocketState.None
  • WebSocketState.Connecting
  • WebSocketState.Closed

我们也可以添加WebSocketState.Aborted到列表中。

考虑到这一事实,如果您不等待关闭请求或发送关闭请求,您可以关闭您的套接字,如下所示:

foreach (var socket in _sockets)
{
    if (socket.State == WebSocketState.Open)
    {
        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
    }
}

我看不到您代码的其余部分。因此,我假设您尝试CloseAsync同步运行该方法。Wait()我建议您在使用异步代码之前三思而后行。您实际上阻塞了当前线程并等待Task完成。你真的需要这个吗?您应该尽可能地使用async一路向下。否则,您可能很容易在异步代码中陷入死锁。

于 2019-07-19T15:53:28.600 回答