同步执行WebSocket SendAsync()

时间:2017-06-06 12:10:25

标签: c# multithreading asynchronous websocket

我有一个Websocket HTTPListener作为服务器,客户端是WebSocket&#39>

我将所有当前客户端保留在列表中,并且我希望有一个函数可以异步地向所有客户端发送信息。

所以我现在拥有的是:

private async Task SendToAll(byte[] buffer)
{
    foreach (WebSocket webSocket in clients)
    {
        await Send(webSocket, buffer, buffer.Length);
    }
}

private async Task Send(WebSocket webSocket, byte[] buffer, int bufferLength)
{
    try
    {
        await webSocket.SendAsync(
            new ArraySegment<byte>(buffer, 0, bufferLength),
            WebSocketMessageType.Text, true,
            CancellationToken.None);
    }
    catch (WebSocketException ex)
    {
        RemoveClient(webSocket, WebSocketCloseStatus.InternalServerError, ex.Message);
    }
}

问题是,如果有大量客户,我打开了一个有意义的线程数,这对我来说是一种浪费。所以我认为Send()函数可以同步发生,但WebSocket没有同步函数,这对我来说很奇怪。

我认为同步运行Task函数不是一个好习惯,有没有一种好方法呢?我不想放弃await

1 个答案:

答案 0 :(得分:0)

  

问题是,如果有大量客户,我打开了一个有意义的线程数,这对我来说是一种浪费。

两个问题:

  1. 你测量了线程吗? “有意义的数字”究竟是多少?
  2. 性能测试是否表明这些线程是“浪费”?
  3. 自写入网络套接字doesn't consume a thread以来,代码已经正在使用线程池。我不希望此代码中的线程数量显着增加。如果 正在创建一些额外的线程,那么这是因为那些额外的线程是有用的。这种I / O绑定操作很难做得更好。

    在一个不相关的附注中,我建议同时发送给所有客户,而不是一次发送一个:

    private async Task SendToAll(byte[] buffer)
    {
      var tasks = clients.Select(webSocket => Send(webSocket, buffer, buffer.Length));
      await Task.WhenAll(tasks);
    }