Open shallowtek opened 2 months ago
Some additional info and what I did to resolve.
I needed to remove using statement on gzipStream and instead dispose on a finally block of a try/catch/finally withing the streamContent using statement from your example.
If you have the time maybe you can review if this will still ensuring same performance and best practices.
` private async Task
// generate a movie poster of 5MB
var random = new Random();
var generatedBytes = new byte[5242880];
random.NextBytes(generatedBytes);
var posterForCreation = new PosterForCreation()
{
Name = "A new poster for The Big Lebowski",
Bytes = generatedBytes
};
using (var memoryContentStream = new MemoryStream())
{
await JsonSerializer.SerializeAsync(
memoryContentStream,
posterForCreation);
memoryContentStream.Seek(0, SeekOrigin.Begin);
using (var request = new HttpRequestMessage(
HttpMethod.Post,
"api/movies/d8663e5e-7494-4f81-8739-6e0de1bea7ee/posters"))
{
request.Headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.AcceptEncoding.Add(
new StringWithQualityHeaderValue("gzip"));
using (var compressedMemoryContentStream = new MemoryStream())
{
var gzipStream = new GZipStream(
compressedMemoryContentStream,
CompressionMode.Compress);
memoryContentStream.CopyTo(gzipStream);
gzipStream.Flush();
compressedMemoryContentStream.Position = 0;
using (var streamContent = new StreamContent(compressedMemoryContentStream))
{
streamContent.Headers.ContentType =
new MediaTypeHeaderValue("application/json");
streamContent.Headers.ContentEncoding.Add("gzip");
request.Content = streamContent;
try
{
var response = await httpClient.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead);
response.EnsureSuccessStatusCode();
var stream = await response.Content.ReadAsStreamAsync();
var poster = await JsonSerializer.DeserializeAsync<Poster>(
stream,
_jsonSerializerOptionsWrapper.Options);
// This throws closed stream exception when trying to return
// I am using the try catch finally to return and then dispose of gzipStream
return poster;
}
catch
{
// catch certain exceptions
}
finally
{
gzipStream.Dispose();
}
}
}
}
}
}`
I just spotted I can use the leavOpen flag in gzipStream contrustctor to keep this stream open. Possibly this is best option?
I just spotted I can use the leavOpen flag in gzipStream contrustctor to keep this stream open. Possibly this is best option?
This actually doesn't work. Still get the stream closed error when trying to return poster object. Hmmm.
For now I will keep the finally block to close the gzipStream. without it I get the exception when I try return poster response in the try block.
Hi Kevin,
Following your compression example ensuring the correct nesting of the using statements, when I try to return the Posters Object I get a Closed Stream Exception.
I am wondering if some using statements need to be changed for this sample to show how an object can be returned.
"status": 500, "detail": "Cannot access a closed Stream.", "exception": { "details": "System.ObjectDisposedException: Cannot access a closed Stream.\n at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)\n at System.IO.Compression.DeflateStream.PurgeBuffers(Boolean disposing)\n at System.IO.Compression.DeflateStream.Dispose(Boolean disposing)\n at System.IO.Stream.Close()\n at System.IO.Compression.GZipStream.Dispose(Boolean disposing)\n at System.IO.Stream.Close()\n