Cancel C# 4.5 TcpClient ReadAsync by timeout

◇◆丶佛笑我妖孽 提交于 2019-12-05 08:31:49

so I know that was from a long time but google still drive me here and I saw there is none marked as answer

for me, I solve like that I make an extension to add a method ReadAsync that takes extra timeout

        public static async Task<int> ReadAsync(this NetworkStream stream, byte[] buffer, int offset, int count, int TimeOut)
    {
        var ReciveCount = 0;
        var receiveTask = Task.Run(async () => { ReciveCount = await stream.ReadAsync(buffer, offset, count); });
        var isReceived = await Task.WhenAny(receiveTask, Task.Delay(TimeOut)) == receiveTask;
        if (!isReceived) return -1;
        return ReciveCount;
    }

so if it returned -1 that mean the read timed out

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<int> ReadAsyncWithTimeout(this NetworkStream stream, byte[] buffer, int offset, int count)
    {
        if (stream.CanRead)
        {

            Task<int> 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.

giammin

You have to implement it by yourself: it is not available in that class.

you should use a timer that will kill the async operation after a timespan or use the Read sync version in a a backgroundthread.

there you can find an example: Implementing a timeout with NetworkStream.BeginRead and NetworkStream.EndRead

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!