【问题标题】:Semaphores and Web Sockets信号量和 Web 套接字
【发布时间】:2015-06-18 20:02:59
【问题描述】:

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

此 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 方法,并让其他线程等待前一个线程完成。

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

【问题讨论】:

  • Hmmmm. 可能完全不符合标准,但在我看来,该循环内的 Semaphore 实例化并不可靠。您是否尝试过将信号量实例移到 外部 foreach?

标签: c# multithreading sockets locking semaphore


【解决方案1】:

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

我建议您使用 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();
            }
       }
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 2012-05-15
    • 2019-02-14
    • 1970-01-01
    相关资源
    最近更新 更多