最近我开始使用新的C#5.0 "async"和"await"关键字。我认为我已经掌握了这个技巧,但是意识到一件事情让我产生了疑问。以下是我如何异步地从远程TcpClient接收数据的方式。一旦我接受连接,我调用这个函数:
static async void ReadAsync(TcpClient client)
{
NetworkStream ns = client.GetStream();
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
while(client.Connected)
{
int bytesRead = await ns.ReadAsync(buffer, 0, buffer.Length);
ms.Write(buffer, 0, bytesRead);
if (!ns.DataAvailable)
{
HandleMessage(ms.ToArray());
ms.Seek(0, SeekOrigin.Begin);
}
}
}
在接收数据后,循环一直运行而没有读取任何内容。我在循环中使用了 Console.WriteLine 进行测试。请问我的使用方法正确吗?我感觉不应该使用 while 循环...
DataAvailable
?那与消息等没有任何关系。主要用途是决定是读取同步还是异步。你也从未清除后备缓冲区 - 你倒带,但你没有清除。 - Marc Gravellasync void
。不返回任何内容的异步方法应该使用async Task
。有许多原因,其中最重要的原因可能是未处理的异常可能会导致非常糟糕、意想不到的行为。 - Daniel MannDataAvaliable
吗?根据MSDN:使用DataAvailable
属性来确定数据是否准备好进行读取。如果DataAvailable
为真,则对Read
的调用将立即返回。 - Yuval ItzchakovDataAvailable
时,他们都在不适当地使用它(尝试检测消息/帧的结尾 - 这不是它的含义)。 - Marc Gravell