信号量和 Web 套接字

本文关键字:套接字 Web 信号量 | 更新日期: 2023-09-27 17:56:56

我正在尝试理解并修复我收到的异常:

此 WebSocket 实例已经有一个未完成的"SendAsync"调用。可以同时调用 ReceiveAsync 和 SendAsync,但最多允许同时对它们执行一个未完成的操作。

所以我有多个线程转到一个想要向特定客户端发送特定信息的处理程序。

当客户端连接

时,将从该客户端的特定连接创建映射,以链接到他或她希望通过 Web 套接字连接流式传输到它们的数据。

我的代码如下所示:

foreach (KeyValuePair<socketInfo, data> pair in mapping)
        {
            //Get the unique sendAsync per connection
            WebSocketSendAsync sendAsync = pair.Key.sendAsync;
            //Get the data the specific connection wnats
            dynamic info = fillData(pair.Value);
            //Convert the data to send to bytes
            string sendInfo = Newtonsoft.Json.JsonConvert.SerializeObject(attributeInfo);
            byte[] infoBytes = System.Text.Encoding.UTF8.GetBytes(sendInfo);
            //Send the data
            Semaphore send = new Semaphore(1, 1);
            send.WaitOne();
            await sendAsync(new ArraySegment<byte>(infoBytes), 1, false, pair.Key.callCancelled);
            send.Release(1);
        }

我知道他们一次只能有一个 sendAsync(即使多个线程正在尝试这样做?),所以我认为信号量将是解决这个问题的正确方法。我希望一次只有一个线程能够使用 await sendAsync 方法,并让其他线程等到前一个线程完成。

这是我第一次使用信号量,所以我不确定为什么它不起作用,有什么帮助吗?

信号量和 Web 套接字

问题似乎是在每个循环上创建的信号量实例。相反,它应该创建一次,然后您可以使用此实例来保护代码不被多个线程同时访问。

我建议你使用SemaphoreSlim而不是Semaphore,因为你在代码中使用async/await。此类有一个 WaitAsync 方法,这是一个可等待的方法。

public class MyClass
{
   SempahoreSlim _semaphore = new SemaphoreSlim(1, 1);
   public void Foo(/*...*/)
   {
       foreach(/*...*/)
       {
            /*...*/
            await _semaphore.WaitAsync();
            try
            {
                await sendAsync(/*...*/);
            }
            finally
            {
                _semaphore.Release();
            }
       }
   }
}