I recently started using the new C#5.0 "async" and "await" keywords. I thought I got the twist but realized one thing that made me doubt. Here's how I was asynchronously receiving data from a remote TcpClient. Once I accept the connection I call this function :
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);
}
}
}
After data is received, the loop just goes on and on without reading anything. I tested this with a Console.WriteLine in the loop. Am I using it correctly? I feel I should not be using a while loop...
The TcpClient.Connected
value is not updated immediately. According to MSDN:
true
if the Client socket was connected to a remote resource as of the most recent operation; otherwise,false
.
So having TcpClient.Connected
as a while loop condition is not a good choice.
TcpClient.DataAvailable
is used for synchronous operations and do not used for asynchronous.
Update your code to:
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
return 0, it means TCP connection closing or closed. In MSDN:
The value of the
TResult
parameter contains the total number of bytes read into the buffer. The result value can be less than the number of bytes requested if the number of bytes currently available is less than the requested number, or it can be 0 (zero) if the end of the stream has been reached.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With