我最近开始使用新的 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 循环......
The TcpClient.Connected
值不会立即更新。根据 MSDN:
true
如果客户端套接字已连接到远程资源最近的手术;否则,false
.
所以有TcpClient.Connected
作为 while 循环条件不是一个好的选择。
TcpClient.DataAvailable
用于同步操作,不用于异步操作。
将您的代码更新为:
static async void ReadAsync(TcpClient client)
{
NetworkStream ns = client.GetStream();
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
while(true) {
int bytesRead = await ns.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead <= 0)
break;
ms.Write(buffer, 0, bytesRead);
HandleMessage(ms.ToArray());
ms.Seek(0, SeekOrigin.Begin);
}
}
When ReadAsync
返回0,表示TCP连接关闭或者已关闭。在 MSDN 中:
的价值TResult
参数包含读入缓冲区的总字节数。如果当前可用字节数小于请求的字节数,则结果值可能小于请求的字节数;如果已到达流末尾,则结果值可能为 0(零)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)