Стоит ли возвращать из метода IDispose-объект?
От: vaa https://www.youtube.com/playlist?list=PLtrvASfI1KW7VOYRKjglcagQzWLoxlncl
Дата: 05.03.22 04:46
Оценка:
Я имею ввиду следующее:

//имеем метод 
public async Task<Stream> DownloadAsync() {
    try {
         return await response.Content.ReadAsStreamAsync();
    }
    finally { response.Dispose(); }
}
/// используем
scope {
... x = new();
(await x.DownloadAsync()).CopyToAsync(File.Create("1.txt"));
}


если я попытаюсь его использовать, то получу ошибку Cannot access a disposed object.
Как эффективно сохранить стрим в файл без копирования в массив?
Правильно ли я понимаю, что даже убрав вызов response.Dispose() все равно после выхода из скоупа
response утилизируется вместе с x?
Re: Стоит ли возвращать из метода IDispose-объект?
От: samius Россия http://sams-tricks.blogspot.com
Дата: 05.03.22 05:08
Оценка: 10 (1)
Здравствуйте, vaa, Вы писали:

vaa>Я имею ввиду следующее:


vaa>если я попытаюсь его использовать, то получу ошибку Cannot access a disposed object.

vaa>Как эффективно сохранить стрим в файл без копирования в массив?
Примерно так и эффективно, нужно только уничтожать респонз после сохранения файла.

vaa>Правильно ли я понимаю, что даже убрав вызов response.Dispose() все равно после выхода из скоупа

vaa>response утилизируется вместе с x?
Когда-нибудь утилизируется.

Но лучше, конечно, сделать это явно за сохранением файла.
И поставить await перед CopyToAsync, что бы за ним можно было сделать Dispose респонса.

using (var response = ....)
{
    using (var sourceStream = await response.Content.ReadAsStreamAsync())
    using (var destStream = File.Create(....)) // тоже надо же освободить
        await sourceStream.CopyToAsync(destStream);
}
Re: Стоит ли возвращать из метода IDispose-объект?
От: Ночной Смотрящий Россия  
Дата: 05.03.22 08:00
Оценка: 9 (2) +4
Здравствуйте, vaa, Вы писали:

vaa>Я имею ввиду следующее:


Тут все зависит как ты это оформишь. Если как у тебя в примере — DownloadAsync, то велика вероятность что задиспозить забудут. А вот если обозвать CreateDownloadStream, то слово Create в названии как бы намекает, что обязанность диспоза за позвавшим.
Альтернативный вариант, если ты вообще не хочешь полагаться на корректный вызов — передавать лямбду:
public async Task DownloadAsync(Action<Stream> streamHandler)
{
    try
    {
      streamHandler(await response.Content.ReadAsStreamAsync());
    }
    finally { response.Dispose(); }
}
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.