Home > Blockchain >  IDisposable objects with using statements inside an if block get disposed prematurely when they'
IDisposable objects with using statements inside an if block get disposed prematurely when they'

Time:11-04

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();
}
  • Related