首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关闭WebSocket线程安全

关闭WebSocket线程安全
EN

Stack Overflow用户
提问于 2017-03-14 09:42:13
回答 2查看 395关注 0票数 0

使用System.Net.WebSockets.WebSocket,我在一个线程中有一个读循环。

代码语言:javascript
复制
var result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

我写的另一篇文章。

代码语言:javascript
复制
lock (ws)
    ws.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None).Wait();

这个很好用。

我的问题是,我如何才能干净利落地关闭这种联系?

任何试图关闭的尝试都会导致异常:

代码语言:javascript
复制
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye", CancellationToken.None);
InvalidOperationException: 'Concurrent reads are not supported.'

我尝试将一个CancellationToken传递给ws.ReceiveAsync,以便在接收循环中调用ws.CloseAsync。它没有中断ReceiveAsync调用,而是在下一条消息到达时返回。

是否可以干净地关闭read循环外的套接字。我可以实现一个“关闭连接”消息,但是当在WebSocket协议中有一个发送关闭消息的概念时,这似乎有点过分了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-17 14:40:22

在这种情况下,您需要调用CloseOutputAsync并在读取中处理CloseSent消息类型。-斯蒂芬·克利里3月14日13时49分

您可以在另一个线程等待CloseOutputAsync时调用ReceiveAsync

票数 0
EN

Stack Overflow用户

发布于 2017-03-14 12:50:22

我在这段代码中没有看到并发读取--如果您只从单个线程调用ReceiveAsync,并且在启动下一个线程之前等待操作的结果,则不应该出现此异常。扔到哪里去了?

编写部分的建议:如果使用锁和阻塞写入(使用.Wait()),则会阻塞完整线程(可能运行其他句柄),这可能不是您想要的。最好使用SemaphoreSlim,您可以这样做:

代码语言:javascript
复制
await semaphore.WaitAsync();
try
{
    await ws.SendAsync();
}
finally
{
    semaphore.Release();
}

如果错误消息的文本不精确,而且实际上它抱怨并发的SendClose,那么您也可以使用相同的信号量来保护Close调用:

代码语言:javascript
复制
await semaphore.WaitAsync();
try
{
    await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye", CancellationToken.None);
}
finally
{
    semaphore.Release();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42782451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档