What would the proper way to cancel TcpClient ReadAsync operation by timeout and catch this timeout event in .NET 4.5?
TcpClient.ReadTimeout seems to be applied to
Edit: the following gist is a workaround I did for this. https://gist.github.com/svet93/fb96d8fd12bfc9f9f3a8f0267dfbaf68
Original:
I really liked the answer from Khalid Omar and did my own version of it which I thought was worth sharing:
public static class TcpStreamExtension
{
public static async Task ReadAsyncWithTimeout(this NetworkStream stream, byte[] buffer, int offset, int count)
{
if (stream.CanRead)
{
Task readTask = stream.ReadAsync(buffer, offset, count);
Task delayTask = Task.Delay(stream.ReadTimeout);
Task task = await Task.WhenAny(readTask, delayTask);
if (task == readTask)
return await readTask;
}
return 0;
}
}
It is more or less the same thing except slightly differently formatted in a way that is more readable (to me), and more importantly it does not use Task.Run
I wasn't sure why it was used in his example.
Edit:
The above may seem good in a first glance but I found out it causes some problems. The readAsync call seems to leak if no data comes in, and in my case it seems that it reads a later write and the data is essentially returned within a place in memory no longer used.