使用ReadAsStreamAsync和StreamReader时出现ArgumentException错误,原因是流不可读。

8

我有以下代码来读取和处理Http get请求的响应,使用StreamReader:

try
{
    Stream stream = await ExecuteRequestAsync(uriBuilder.Uri, HttpMethod.Get).ConfigureAwait(false);
    if (stream != null)
    {
        using (StreamReader sr = new StreamReader(stream))
        {
            using (JsonTextReader reader = new JsonTextReader(sr))
            {
                ...
            }
        }
    }
}
catch (Exception ReadingStreamException)
{

}

private async Task<stream> ExecuteRequestAsync(Uri uri, HttpMethod method)
{
    Stream stream;
    using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, uri))
    {
    try
    {
        stopwatch.Start();
        using (HttpResponseMessage responseMessage = await this.httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false))
        {
            stream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
        }
    }
    catch(Exception GettingStreamException)
    {
        // Error checking code
    }

    return stream;
}

使用(StreamReader sr = new StreamReader(stream))的这一行代码会抛出一个类型为ArgumentException的ReadingStreamException异常,详细信息是"Stream was not readable"。以上代码有什么问题吗?

1个回答

12

这是因为当您处理 HttpResponseMessage 时,它会处理底层流。来自源代码

private HttpContent content;
protected virtual void Dispose(bool disposing)
{
    if (disposing && !disposed)
    {
        disposed = true;
        if (content != null)
        {
            content.Dispose();
        }
    }
}

你可以复制流,或者只是不处理HttpResponseMessage,因为当将其传递给StreamReader时,会自动处理基础流。我会选择后者:

private async Task<Stream> ExecuteRequestAsync(Uri uri, HttpMethod method)
{
    Stream stream = null;
    using (HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, uri))
    {
       try
       {
          stopwatch.Start();
          HttpResponseMessage responseMessage = await httpClient
                                                      .SendAsync(httpRequestMessage)
                                                      .ConfigureAwait(false);

          stream = await responseMessage.Content.ReadAsStreamAsync()
                                                .ConfigureAwait(false);
       }
       catch(Exception GettingStreamException)
       {
          // Error checking code
       }  
    }
    return stream;
}

小建议:有一种情况下,HttpResponseMessage中的数据可能不会被处理:当创建HttpResponseMessage对象并在分配StreamReader之前发生异常时。因此,我将该函数完全删除,并将代码移动到一个单独的位置以获取HttpResponseMessage并使用StreamReader读取它。 - Romonov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接