Когда заканчивается область действия одноразовой переменной в течение времени l oop? - PullRequest
1 голос
/ 02 апреля 2020

У меня есть время l oop, в котором я что-то делаю с потоком памяти, а именно передаю его другим объектам, которые заполняют поток или читают из него. Код выглядит примерно так:

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);
    }
}

Мой вопрос таков: будет ли memoryStream располагаться на каждой итерации или когда закончится l oop?

Пока вопрос C# 8 Использование декларации Scope Confusion отвечает на этот топи c Как правило, он не дает явного ответа на вопрос о области действия одноразовых переменных в то время как -l oop.

Ответы [ 3 ]

5 голосов
/ 02 апреля 2020

Поток памяти будет располагаться в конце блока while l oop, поэтому один раз для каждой итерации while l oop.

2 голосов
/ 02 апреля 2020

Ответ Шона правильный, но я хотел бы немного расширить, чтобы объяснить, почему это правильно:

Это на самом деле вопрос о c # 8 с использованием объявления :

Объявление использования - это объявление переменной, которому предшествует ключевое слово using. Он сообщает компилятору, что объявленная переменная должна располагаться в конце охватывающей области.

По сути, объявление using компилируется как оператор using, который заканчивается непосредственно перед огибающая область заканчивается. Другими словами, ваш код переводится на это:

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

Теперь это очень ясно, когда распоряжается memoryStream - в конце каждой while итерации.

1 голос
/ 02 апреля 2020

Вот как будет выполняться ваш код (я упростил ваш метод, включив в него только необходимую часть):

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

        try
        {
        }

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

Итак, как вы можете видеть, memoryStream будет располагаться в каждом итерация. Промежуточные шаги и результаты компиляции кода вы можете найти здесь: SharpLap .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...