Description
I would like to read asynchronously from a NetworkStream
or SSLStream
using their abstract Stream
parent class. There are different ways to read asynchronously from stream:
- Asynchronous Programming Model (APM): It uses
BeginRead
andEndRead
operations. - Task Parallel Library (TPL): It uses
Task
and creates task continuations. - Task-based Asynchronous Pattern (TAP): Operations are suffixed Async and
async
andawait
keyword can be used.
I am mostly interested using the TAP pattern to achieve asynchronous read operation. Code below, asynchronously read to the end of stream and returns with the data as byte array:
internal async Task<byte[]> ReadToEndAsync(Stream stream)
{
byte[] buffer = new byte[4096];
using (MemoryStream memoryStream = new MemoryStream())
{
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
while (bytesRead != 0)
{
// Received datas were aggregated to a memory stream.
await memoryStream.WriteAsync(buffer, 0, bytesRead);
bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
}
return memoryStream.ToArray();
}
}
The buffer size is 4096kB. If the transferred data is more than the buffer size then it continues to read until 0 (zero), the end of the stream. It works with FileStream
but it hangs indefinitely at the ReadAsync
operation using NetworkStream
or SslStream
. These two stream behave differently than other streams.
The problem lies behind that the network stream ReadAsync
will only return with 0 (zero) when the Socket
communication is closed. However I do not want to close the communication every time a data is transferred through the network.
Question
How can I avoid the blocking call of the ReadAsync
without closing the Socket
communication?