Ich muss umfangreiche Daten in einer HTTP-Post-Anfrage an einen Server senden, der Gziped codierte Anfragen unterstützt.So komprimieren HTTP-Anfrage im laufenden Betrieb und ohne Laden von komprimiertem Puffer im Speicher
Ausgehend von einer einfachen
public async Task<string> DoPost(HttpContent content)
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync("http://myUri", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Ich habe soeben einen Pre Kompression
public async Task<string> DoPost(HttpContent content, bool compress)
{
if (compress)
content= await CompressAsync(content);
return await DoPost(content);
}
private static async Task<StreamContent> CompressAsync(HttpContent content)
{
MemoryStream ms = new MemoryStream();
using (GZipStream gzipStream = new GZipStream(ms, CompressionMode.Compress, true))
{
await content.CopyToAsync(gzipStream);
await gzipStream.FlushAsync();
}
ms.Position = 0;
StreamContent compressedStreamContent = new StreamContent(ms);
compressedStreamContent.Headers.ContentType = content.Headers.ContentType;
compressedStreamContent.Headers.Add("Content-Encoding", "gzip");
return compressedStreamContent;
}
Es funktioniert perfekt, aber komprimieren Daten werden komplett in den Speicher geladen, bevor Anfrage senden. I möchte in der Lage sein, Daten während des Sendens in einem Streaming-Weg zu komprimieren.
, es zu tun, ich habe folgenden Code versucht:
private static async Task<HttpContent> CompressAsync2(HttpContent content)
{
PushStreamContent pushStreamContent = new PushStreamContent(async (stream, content2, transport) =>
{
using (GZipStream gzipStream = new GZipStream(stream, CompressionMode.Compress, true))
{
try
{
await content.CopyToAsync(gzipStream);
await gzipStream.FlushAsync();
}
catch (Exception exception)
{
throw;
}
}
});
pushStreamContent.Headers.ContentType = content.Headers.ContentType;
pushStreamContent.Headers.Add("Content-Encoding", "gzip");
return pushStreamContent;
}
aber es geht nie aus copyToAsync (GZipStream). FlushAsync wird niemals ausgeführt und es wird keine Ausnahme ausgelöst, und Fiddler sieht keinen Post gestartet.
Meine Fragen sind:
- Warum CompressAsync2 nicht funktioniert?
- Wie komprimiert man während des Sendens und ohne den komprimierten Puffer im Speicher zu laden?
Jede Hilfe würde sehr geschätzt werden.
'PushStreamContent' unterstützt (derzeit)' async' lambdas nicht. –
@Stephen Cleary: Du hast recht, ich hätte nachsehen sollen! Und ich kann nicht von PushStreamContent abgeleitet werden, um SerializeToStreamAsync zu überlasten (nur zu viele interne). Kannst du eine Lösung sehen? – MuiBienCarlota
Humm, es kann am einfachsten sein, einfach ['PushStreamContent' zu nehmen und es zu modifizieren] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Net.Http.Formatting/PushStreamContent.cs), um' 'zu unterstützen asynchrone Lambdas. Es ist seit ein paar Monaten auf meiner "Todo" -Liste, bin einfach nicht dazu gekommen. –