3

I have a while loop wherein I do something with a memory stream - namely passing it to other objects that fill the stream or read from it. The code looks something like this:

public async void CaptureImages(CancellationToken ct)
{
    while(!ct.IsCancellationRequested)
    {
        await using var memoryStream = new MemoryStream();

        await this.camera.CaptureImage(memoryStream, ct);
        await this.storage.StoreImage(memoryStream, ct);
    }
}

My question is: Will memoryStream be disposed in every iteration or once the loop ends?

While the question C# 8 Using Declaration Scope Confusion answers this topic generally, it does not explicitly answer the question about the scope of disposable variables in a while-loop.

Spontifixus
  • 6,570
  • 9
  • 45
  • 63

3 Answers3

6

The memory stream will be disposed at the end of the while loop block, so once for every while loop iteration.

Sean
  • 60,939
  • 11
  • 97
  • 136
4

Sean's answer is correct, but I wanted to expand a little bit to explain why it's correct:

This is actually a question about c#8 using declaration:

A using declaration is a variable declaration preceded by the using keyword. It tells the compiler that the variable being declared should be disposed at the end of the enclosing scope.

Basically, the using declaration is compiled as a using statement, that ends just before the enclosing scope ends. In other words, your code gets translated to this:

while(!ct.IsCancellationRequested)
{
    await using(var memoryStream = new MemoryStream())
    {
        await this.camera.CaptureImage(memoryStream, ct);
        await this.storage.StoreImage(memoryStream, ct);
    }
}

Now this is very clear when the memoryStream gets disposed - at the end of every while iteration.

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
2

This is how your code will be executed (I've simplified your method to include just the necessary part):

public void CaptureImages(CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        MemoryStream memoryStream = new MemoryStream();

        try
        {
        }

        finally
        {
            if (memoryStream != null)
            {
                ((IDisposable)memoryStream).Dispose();
            }
        }
    }
}

So as you can see, the memoryStream will be disposed in every iteration. You can find the intermediate steps and results of your code compilation here in SharpLap.

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109