运行此代码时:
private async void StartChat(Object obj)
{
TcpClient me = (TcpClient)obj;
UpdateChatBox("Attempting read from server.");
myBuffer = new byte[BUFFER_SIZE];
while (true)
{
var myStream = me.GetStream();
myStream.BeginRead(myBuffer, 0, BUFFER_SIZE, new AsyncCallback(UpdateChatBoxAsync), myStream);
if (messageToSend)
{
await myStream.WriteAsync(myMessage, 0, myMessage.Length);
}
}
}我从BeginRead收到以下IO异常
无法从传输连接读取数据:无法执行套接字上的操作,原因是系统缺少足够的缓冲区空间或队列已满。
下面是BeginRead的回调方法:
private void UpdateChatBoxAsync(IAsyncResult result)
{
var stream = result.AsyncState as NetworkStream;
int bytesRead = stream.EndRead(result);
if (bytesRead > 0)
{
String newMessage = NetworkUtils.GetString(myBuffer);
UpdateChatBox(newMessage);
}
}有人能说明一下这个例外被提出的原因吗?我试着每次在while循环开始时重新创建缓冲区,但是虽然这样做可以避免引发异常,但我不会接收来自服务器的消息。
我还试图将myBuffer重置为UpdateChatBoxAsync末尾的空数组,这也不起作用。
任何帮助都将不胜感激。
发布于 2014-02-09 10:07:50
你在没有任何节流的情况下运行一个无限循环。您正在以CPU所能完成的速度发出异步读取调用。这就产生了无限数量的未完成的操作。
当最后一次读取完成时,您应该发出下一次读取(最常见的是通过回调完成)。
只需加上
if (myStream.DataAvailable)您避免读取,但仍然烧掉一个CPU核心。这只是缓解症状之一。而不是解决根本原因。
似乎您根本不应该执行异步IO,因为您对阻塞没有任何问题。你阻塞了一个线程,烧掉了100%的核心。如果这是可以接受的,甚至不用担心异步IO。
或者,使用await ReadAsync。
发布于 2014-02-09 06:52:52
我找到了解决办法。
在尝试BeginRead之前,我检查流是否有任何可用的数据使用NetworkStream.DataAvailable,或者在我的例子中是myStream.DataAvailable
所以新的代码块看起来就像
if (myStream.DataAvailable){
myStream.BeginRead(myBuffer, 0, BUFFER_SIZE, new AsyncCallback(UpdateChatBoxAsync), myStream);
}https://stackoverflow.com/questions/21652297
复制相似问题