C#StreamReader:如何绑定同步ReadBlock调用的最大时间?

时间:2018-02-15 07:11:14

标签: c# httpwebrequest streamreader

我想限制读取流所需的最长时间。 ReadTimeout属性不限制最大时间,仅当ReadTimeout窗口中未收到任何数据时才适用。如何确保以下代码执行时间不超过N秒,如果超过N秒,我想取消并释放所有底层资源。

          using (WebResponse response = ExecuteHttpRequest(
                httpRequestInputs.EndpointUrl,
                new HttpMethod(httpRequestInputs.Method),
                httpRequestInputs.Body,
                httpRequestInputs.Headers))
            {
                statusCode = ((HttpWebResponse)response).StatusCode;

                using (var responseStream = response.GetResponseStream())
                {
                    using (var streamReader = new StreamReader(responseStream))
                    {
                        var responseContent = new char[m_maxResponseSizeToBeRead];
                        var bytesRead = streamReader.ReadBlock(responseContent, 0, m_maxResponseSizeToBeRead);
                        if (!streamReader.EndOfStream){
                            isResponseSizeLimitExceeded = true;
                        }
                        else
                        {
                            result = new String(responseContent, 0, bytesRead);
                        }
                    }
                }
            }

我可以将其包装在某个任务中,然后在N秒后取消该任务吗?这会释放在任务中创建的资源吗?

1 个答案:

答案 0 :(得分:0)

您可以轻松继承StreamReader并添加自己的功能:

public class StreamReaderWithMaxTime : StreamReader
{
    public TimeSpan MaxTime { get; set; } = new TimeSpan(0, 1, 0);
    public DateTime? Start { get; set; }

    public override int ReadBlock(char[] buffer, int index, int count)
    {
        if (Start == null)
            Start = DateTime.Now;

        if (Start.Value.Add(MaxTime) < DateTime.Now)
            throw new Exception("Timeout! Max readtime reached!");

        int result = 0;
        Thread t = new Thread(() => result = base.ReadBlock(buffer, index, count));
        t.Start();
        if (!t.Join(Start.Add(MaxTime) - DateTime.Now))
        {
            t.Abort();
            throw new Exception("Timeout! Max readtime reached!");
        }

        return result;
    }
}