大きなオブジェクトをストリーミングする必要があります。私はそれをチャンクで送る方法を理解することができません。ただし、投稿されたコードはstream.Flush()が一度だけ呼び出されます。ですから、本質的に私はオブジェクトをバッファリングしています。 stream.Flush()複数回に電話するにはどうすればいいですか?私がコレクションを持っていれば、ループでストリーム/フラッシュできます。だから私はどのように大きなオブジェクトでそれを行うのですか?ストリーミングJson - 大きなオブジェクトを持つPushStreamContent
サーバコード:
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);
}
}
}
}
フラッシュする必要はありません。 PushStreamContentの基本的なことは、基本的に、それに書き込まれるすべてのデータは、コンテンツをバッファリングせずに直接クライアントにストリーミングされることです。それで、完全なJSON表現がメモリにあることを確認してください。 – ckuri
また、https://www.thomaslevesque.com/2013/11/30/uploading-data-with-httpclient-using-a-push-model/に従って、JSONをストリームしたい場合は、PushStreamContentの代わりに新しいObjectContent(document、new JsonMediaTypeFormatter())を使用してください。これは同じ作業を行う必要がありますが、はるかに簡潔です。 – ckuri
@ckuri ...その記事はダウンロードしないアップロードに焦点を当てています。また、私は、データがflush()が呼び出されるまでストリーミングされているとは思っていません。少なくとも、コードを実行するときに見ている方法です。 –