0

我需要流式传输一个大对象。我无法弄清楚如何分块发送。发布的代码有效,但是stream.Flush()只被调用一次。所以,基本上我正在缓冲对象 - 不好。如何多次调用stream.Flush() ?如果我有一个集合,我可以循环流式传输/刷新。那么我该如何处理一个大对象呢?

服务器代码:

   public async Task<HttpResponseMessage> ConvertToTiffAsync([FromBody] DocumentDto dto)
                {
                    // THIS IS LARGE
                    var document = await _service.ConvertToTiffAsync(dto);
                    var response = Request.CreateResponse();
                    response.Content = new PushStreamContent((stream, content, context) =>
                    {
                        var serializer = new JsonSerializer();
                        using (var writer = new StreamWriter(stream))
                        {
                            using (var jsonTextWriter = new JsonTextWriter(writer))
                            {
                                serializer.Serialize(jsonTextWriter, document);
                                stream.Flush(); // ONLY CALLED ONCE - NEED MANY CALLS
                            }
                        }
                    });
                    return response;
                }

客户代码(此处未进行流式传输,但需要):

using (var client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
            {
                client.Timeout = new TimeSpan(0, 5, 0);
                var stringContent = new StringContent(JsonConvert.SerializeObject(dto), Encoding.UTF8, "application/json");
                using (var httpRequest = new HttpRequestMessage(HttpMethod.Post, endpoint))
                {
                    httpRequest.Content = stringContent;
                    using (HttpResponseMessage response = await client.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
                    {
                        response.EnsureSuccessStatusCode();
                        using (var streamReader = new StreamReader(await response.Content.ReadAsStreamAsync()))
                        using (var jsonReader = new JsonTextReader(streamReader))
                        {
                            var serializer = new JsonSerializer();
                            return await Task.Run(() => serializer.Deserialize<ConvertDocumentDto>(jsonReader)).ConfigureAwait(false);
                        }
                    }
                }
            }
4

1 回答 1

0

您的服务器代码似乎没问题。但是,您的客户端代码似乎无法与服务器正确交互。

如果要将 DocumentD 设置为输入,则需要将 JSON 写入请求,而不是响应。如果您想在内存中没有完整 JSON 的情况下使用服务器操作,则需要 JsonTextReader。所以一般在客户端应该是:

var client = new HttpClient();
var dtoContent = new PushStreamContent((stream, content, context) => {
   var serializer = new JsonSerializer();
    using (var streamWriter = new StreamWriter(stream))
    {
       using (var jsonWriter = new JsonTextWriter(streamWriter))
       { serializer.Serialize(jsonTextWriter, dto); }
    }
});
using (var stream = await client.PostAsync(url, dtoContent).Content.ReadAsStreamAsync())
{
  using (var streamReader = new StreamReader(stream))
  {
    using (var jsonReader = new JsonTextReader(streamReader))
    {
        document = JsonSerializer().Deserialize<Document>(jsonReader);
    }
  }
}

如果您的 DTO 很小,并且您不介意在内存中使用完整的 JSON 而不是 client.PostAsync(url),如果您导入 System.Net,您还可以使用位于 HttpClientExtensions 命名空间中的 client.PostAsJsonAsync(url, dto)。 Http.Formatting.dll。

于 2017-06-06T18:42:11.307 回答