Reputation: 6883
I have an ASP.NET web API server written with C# (v2.2). One of my exposed methods, creating a MemoryStream
and adding data into it. In the end, return it with the return File(ms)
method.
My code looks like this:
[HttpGet]
[Route("my-endpoint")]
public async Task<ActionResult> TestMe()
{
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
await sw.WriteLineAsync($"A,B,C").ConfigureAwait(false);
await sw.WriteLineAsync($"1,2,3").ConfigureAwait(false);
await sw.FlushAsync().ConfigureAwait(false);
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "application/csv");
}
The problem here is that this code not disposing all the stream from the memory for sure. In case that everything was OK, the stream will be closed by the ASP.NET code. If an exception was thrown, the stream won't be disposed.
I thought that the right way to implement it will be (this code is NOT working):
[HttpGet]
[Route("my-endpoint")]
public async Task<ActionResult> TestMe()
{
using (MemoryStream ms = new MemoryStream())
using (StreamWriter sw = new StreamWriter(ms))
{
await sw.WriteLineAsync($"A,B,C").ConfigureAwait(false);
await sw.WriteLineAsync($"1,2,3").ConfigureAwait(false);
await sw.FlushAsync().ConfigureAwait(false);
ms.Seek(0, SeekOrigin.Begin);
return File(ms, "application/csv");
}
}
The problem here is when we are leaving the function (on the return
line). Then, the stream will be disposed before being returned to the client.
How to make my code work safely?
Upvotes: 0
Views: 4281
Reputation: 62492
There's nothing wrong with your first method. If the code throws (either in your method or in the asp.net framework) then eventually the stream and writer will be garbage collected.
If nothing goes from then the File
class will call Dispose
on the memory stream, but as this is just a wrapper over a byte
array nothing will really happen until the garbage collector kicks in, so either way your code is fine.
Upvotes: 2