定期从Task从Http PostAsync响应内容返回

本文关键字:响应 PostAsync 返回 Http Task Stream | 更新日期: 2023-09-27 18:02:47

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

我曾经有过类似于

的代码
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<Stream>对象时,是否有可能像上面的例子中那样定期从流中读取数据?

定期从Task<Stream>从Http PostAsync响应内容返回

ReadAsStreamAsync()只在接收到所有内容后返回的原因是PostAsync()内部使用HttpCompletionOption.ResponseContentRead。你要的是HttpCompletionOption.ResponseHeadersRead

HttpClient上的一些方法有一个接受HttpCompletionOption的重载,这允许你覆盖默认值。不幸的是,PostAsync()没有。显然,这是因为POST请求的响应不应该很长。

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

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