In my MVC controller, i have an action that will populate a stream which i will use later:
[HttpPost]
public async Task<HttpResponseMessage> BuildFileContent(FileParameters fileParams)
{
byte[] output;
if (fileParams != null)
{
using (var stream = new MemoryStream())
{
await Task.Run(() => PopulateFile(fileParams, stream)); // Here i populate the stream
stream.Flush();
output = stream.ToArray();
}
var guid = Guid.NewGuid().ToString();
FileContents.Add(guid, output); // just save the content for later use
return this.Request.CreateResponse(HttpStatusCode.OK, new { Value = guid });
}
return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid parameters");
}
I had this problem because ReSharper is giving out a warning: access on disposed closure
on the line PopulateFile(fileParams, stream)
and pointing out stream
.
I have searched for the meaning of it and it seems that it warns that i could possibly use an already disposed stream.
I want to await the population of the stream because the task could take long.
Is there a way that I can wait the population of the stream without ReSharper giving this warning?
Moreover, i am calling stream
inside the using
clause, the stream should not yet be disposed until i call flush or the last line of the using clause is executed right? So why does ReSharper warn about accessing a disposed stream?
Resharper warns you because you are using the stream inside a lambda expression that can basically be run whenever and not just inside the using
scope.
If this was your code you could dispose of the stream before the task ended and you would have a ObjectDisposedException
on your hands:
Task task = null;
using (var stream = new MemoryStream())
{
task = Task.Run(() => PopulateFile(fileParams, stream)); // Here i populate the stream
stream.Flush();
output = stream.ToArray();
}
await task;
In your case however you await
that operation and dispose the stream only after that operation has finished. So basically you are in the clear, but Resharper evidently doesn't know that.
To clear the warning altogether you can put the using
scope inside the task:
await Task.Run(() =>
{
using (var stream = new MemoryStream())
{
PopulateFile(fileParams, stream);
stream.Flush();
output = stream.ToArray();
}
});
And I recommend you do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With