【发布时间】:2014-07-29 11:36:12
【问题描述】:
我最近开始使用新的 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 循环...
【问题讨论】:
-
因此您已将数据写入
MemoryStream,您在同一个MemoryStream上一遍又一遍地调用HandleMessage,直到有更多数据可用。你预计会发生什么? -
你为什么在这里查看
DataAvailable?这与消息等无关。其主要用途是决定是读取同步还是异步。您也不会清除后台缓冲区 - 您倒带,但您不会清除 -
我觉得我最近一直在发这个帖子,但是 只使用
async void作为事件处理程序。不返回任何内容的异步方法应该是async Task。 有很多原因,其中最重要的可能是未处理的异常会导致非常糟糕的意外行为。 -
@Marc 你确定
DataAvaliable吗?根据 MSDN:Use the DataAvailable property to determine if data is ready to be read. If DataAvailable is true, a call to Read returns immediately. -
@Yuval 不,我说 调用者 可以使用它来决定是读取同步还是异步。如果它不为零,我们可以合理地使用同步读取并期望立即返回。如果它为零,我们应该切换到异步。它没有很多其他用途,而且大多数时候我看到人们触摸
DataAvailable,他们不恰当地使用它(试图检测消息/帧的结尾 - 这是不是是什么意思)
标签: c# asynchronous tcp