Cancel C# 4.5 TcpClient ReadAsync by timeout

前端 未结 4 462
北海茫月
北海茫月 2021-01-11 23:32

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

4条回答
  •  抹茶落季
    2021-01-12 00:15

    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.

提交回复
热议问题