C# 正在使用NetworkStream.beginhead()获取IOException

C# 正在使用NetworkStream.beginhead()获取IOException,c#,ioexception,networkstream,beginread,C#,Ioexception,Networkstream,Beginread,运行此代码时: 专用异步void StartChat(对象obj) { TcpClient me=(TcpClient)obj; UpdateChatBox(“尝试从服务器读取”); myBuffer=新字节[缓冲区大小]; while(true) { var myStream=me.GetStream(); BeginRead(myBuffer,0,BUFFER_SIZE,new AsyncCallback(UpdateChatBoxAsync),myStream); if(messageTo

运行此代码时:

专用异步void StartChat(对象obj)
{
TcpClient me=(TcpClient)obj;
UpdateChatBox(“尝试从服务器读取”);
myBuffer=新字节[缓冲区大小];
while(true)
{
var myStream=me.GetStream();
BeginRead(myBuffer,0,BUFFER_SIZE,new AsyncCallback(UpdateChatBoxAsync),myStream);
if(messageToSend)
{
等待myStream.WriteAsync(myMessage,0,myMessage.Length);
}                
}
}
我从
BeginRead
收到以下IO异常:

无法从传输连接读取数据:无法执行套接字上的操作,因为系统缺少足够的缓冲区空间或队列已满

以下是BeginRead的回调方法:

private void UpdateChatBoxAsync(IAsyncResult结果)
{
var stream=result.asynchState作为NetworkStream;
int bytesRead=stream.EndRead(结果);
如果(字节读取>0)
{
String newMessage=NetworkUtils.GetString(myBuffer);
UpdateChatBox(新消息);
}
}
有人能解释一下提出这一例外的原因吗?每次在while循环开始时,我都尝试重新创建缓冲区,但尽管这样做没有引发异常,但我不会从服务器接收消息

我还尝试在UpdateChatBoxAsync结束时将myBuffer重置为空数组,这也不起作用


任何帮助都将不胜感激。

我已经找到了解决方案

在尝试
BeginRead
之前,我使用
NetworkStream.DataAvailable
或在我的情况下
myStream.DataAvailable

因此,新的工作代码块看起来像

if(myStream.DataAvailable){
BeginRead(myBuffer,0,BUFFER_SIZE,new AsyncCallback(UpdateChatBoxAsync),myStream);
}

您正在运行一个没有任何节流的无限循环。您正在尽可能快地发出异步读取调用。这将创建无限数量的未完成操作

您应该在最后一次读取完成时发出下一次读取(最常见的是通过回调完成)

加上

if (myStream.DataAvailable)
您可以避免读取,但仍会烧掉一个CPU内核。这只是症状之一的缓解。而是修复根本原因

看起来您根本不应该执行异步IO,因为您在阻塞方面没有问题。你阻塞了一个线程并烧掉了100%的内核。如果这是可以接受的,那么就不用再为异步IO操心了


或者,使用
await ReadAsync

这是一个低级Windows错误,WSAENOBUFS。非常不寻常的是在一个开始的电话。可能是,可能是您打开了太多的插座。那么您认为正确的解决方案是什么样的呢?为什么使用await ReadAsync可以解决这个问题?只是想弄清楚。谢谢<代码>等待读取异步仅在当前读取完成后继续处理。这是关键。它不使用任何线程。它使用异步IO。不过,这对你来说并不重要。检查你的CPU利用率,可能在一个内核上消耗100%,因为这是一个无限循环,没有阻塞。