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
BeginReadandEndReadoperations. - Task Parallel Library (TPL): It uses
Taskand creates task continuations. - Task-based Asynchronous Pattern (TAP): Operations are suffixed Async and
asyncandawaitkeyword 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?