0

I'm trying to upload JSON to an Azure blob via a memory stream. When I call UploadAsync my application hangs. If I move the UploadAsync call outside the StreamWriter curly brackets I get a System.ObjectDisposedException: 'Cannot access a closed Stream.' exception. How can I stream the JSON to the blob?

            var blobClient = new BlobClient(new Uri(storageUri), options);

            var serializer = JsonSerializer.Create(this.serializerSettings);

            using (var stream = new MemoryStream())
            {
                using (var writer = new StreamWriter(stream))
                {
                    serializer.Serialize(writer, job);

                    await blobClient.UploadAsync(stream, overwrite: true, cancellationToken: cancellationToken);
                }
            }
Dave Moran
  • 21
  • 4
  • 1) You need to flush the `StreamWriter` after serializing, ideally by placing it in a `using` statement and not closing the underlying stream (see [here](https://stackoverflow.com/q/2666888/3744182)). 2) You need to rewind the `MemoryStream` by setting `stream.Position = 0` before uploading it. No idea if those are causing the hang though. – dbc Jun 19 '20 at 13:25
  • Seems like this is a duplicate of [Is there any way to close a StreamWriter without closing its BaseStream?](https://stackoverflow.com/q/2666888/3744182) and also [Stream.Seek(0, SeekOrigin.Begin) or Position = 0](https://stackoverflow.com/q/7238929). [This answer](https://stackoverflow.com/a/49816317) to [MemoryStream - Cannot access a closed Stream](https://stackoverflow.com/q/10934585) shows exactly what to do. Agree? – dbc Jun 19 '20 at 16:07
  • Thanks for the response. I looked at that post, but it doesn't show the stream being flushed. – Dave Moran Jun 19 '20 at 23:13
  • Disposing of the `StreamWriter` via a `using` statement flushes it. The linked answer shows how to do that without closing the underlying stream. – dbc Jun 19 '20 at 23:26
  • Thanks, I've updated my answer using the linked answer. – Dave Moran Jun 21 '20 at 22:56

1 Answers1

2

I've used the leaveOpen option to keep the memory stream open. I've also rewound the memory stream before uploading to the blob.

            var blobClient = new BlobClient(new Uri(storageUri), options);

            var serializer = JsonSerializer.Create(this.serializerSettings);

            using (var stream = new MemoryStream())
            {
                // Use the 'leave open' option to keep the memory stream open after the stream writer is disposed
                using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
                {
                    // Serialize the job to the StreamWriter
                    serializer.Serialize(writer, job);
                }

                // Rewind the stream to the beginning
                stream.Position = 0;

                // Upload the job via the stream
                await blobClient.UploadAsync(stream, overwrite: true, cancellationToken: cancellationToken);
            }
Dave Moran
  • 21
  • 4