Consider the following code:
using var form = new MultipartFormDataContent();
if (uploadFile)
{
using var fileStream = file.OpenReadStream();
using var fileContent = new StreamContent(fileStream);
form.Add(fileContent, "Upload", fileName);
}
using var otherContent = new StringContent(someJson);
form.Add(otherContent,"Other");
await HttpClient.PostAsync("myApi", form);
I have a web form here, and I only want to upload some file when uploadFile
is true
.
However, the code as is will throw exception:
System.ObjectDisposedException: Cannot access a disposed object
This is because I have the fileStream
and fileContent
with the using
statement inside the if
block. However, those objects get disposed prematurely even though the form which they were added to depends on them later.
If I do not use the using
statement, those objects may not be disposed properly and compile will give warning, too.
What's the best way to handle this scenario without writing duplicated codes?
CodePudding user response:
You are disposing objects that are needed by the MultipartFormDataContent
prematurely. Ideally, its documentation states (or should state) that the given objects will be owned and will be disposed of appropriately, once the form is also disposed.
So it is not the IF's fault.
In other words, don't use the using
keyword in their declarations. It is not your job to dispose of them, unless the MultipartFormDataContent
's documentation says so.
If it says you must dispose of them, then do this:
using var form = new MultipartFormDataContent();
Stream fileStream = null;
StreamContent fileContent = null;
if (uploadFile)
{
fileStream = file.OpenReadStream();
fileContent = new StreamContent(fileStream);
form.Add(fileContent, "Upload", fileName);
}
try
{
using var otherContent = new StringContent(someJson);
form.Add(otherContent,"Other");
await HttpClient.PostAsync("myApi", form);
}
finally
{
fileContent?.Dispose();
fileStream?.Dispose();
}