我正在尝试理解并修复我收到的异常:
此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方法,并让其他线程等到上一个线程完成。
这是我第一次使用信号量,所以我不确定为什么它不起作用,有什么帮助吗?
答案 0 :(得分:4)
问题似乎是你的信号量实例是在每个循环上创建的。它应该被创建一次,然后您可以使用此实例来保护您的代码不被同时多个线程访问。
我建议您使用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();
}
}
}
}