【问题标题】:Periodically read from Task<Stream> returned from Http PostAsync response content定期从 Http PostAsync 响应内容返回的 Task<Stream> 中读取
【发布时间】:2016-08-18 23:12:18
【问题描述】:

我有一个应用程序,在将文件发布到服务器后,服务器会定期向客户端应用程序返回有关其响应中升级过程的消息。

我曾经有过类似的代码

using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse())
{
    using (Stream responseStream = httpResponse.GetResponseStream())
    {
        using (var reader = new StreamReader(stream))
        {
            while(!streamReader.EndOfStream)
            {
                var str = streamReader.ReadLine();
                // Do something with str
            }
        }
    }
}

在更新我的代码以利用 HttpClient 类后,我正在努力寻找一种与上述代码相同的方法。

var response = client.PostAsync(uploadUrl, content).Result;

var stream = response.Content.ReadAsStreamAsync().Result;

var streamReader = new StreamReader(stream);

// Superfluous due to the fact we are already at end of stream
while(!streamReader.EndOfStream)
{
    var str = streamReader.ReadLine();
    // Do something with str
}

如果我尝试类似上面的方法,那么我们会等到整个流都被填充后,然后再一次返回,因为使用了response.Content.ReadAsStreamAsync().Result 调用。这不适合,因为我希望从服务器返回时实时显示信息。

当我们有一个Task&lt;Stream&gt; 对象时,是否可以像上面示例中那样定期从流中读取?

【问题讨论】:

    标签: c# http async-await


    【解决方案1】:

    ReadAsStreamAsync()之所以在收到所有内容后才返回,是因为PostAsync()内部使用了HttpCompletionOption.ResponseContentRead。你要的是HttpCompletionOption.ResponseHeadersRead

    HttpClient 上的某些方法具有接受 HttpCompletionOption 的重载,这允许您覆盖默认值。不幸的是,PostAsync() 没有。显然,这是因为responses to POST requests are not supposed to be long

    但是你仍然可以使用通用的SendAsync() 方法做你想做的事:

    var response = client.SendAsync(
        new HttpRequestMessage(HttpMethod.Post, uploadUrl) { Content = content },
        HttpCompletionOption.ResponseHeadersRead).Result;
    

    【讨论】:

      猜你喜欢
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      相关资源
      最近更新 更多