Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

TryOpenExisting() и использование Discards (пустых переменных) на обьектах которые наследуют IDisposable

#c_sharp #c_sharp_faq #mutex #c_sharp_70


Мне нужно только результат функции, который записывается в переменную existing. 

Boolean existing = Mutex.TryOpenExisting(name: key, rights: MutexRights.ReadPermissions,
result: out Mutex _);


Могу ли я использовать "Пустую переменную" в этом коде? Вызовет ли она Dispose();
для этого обьекта автоматически?

Или правильным было бы обьявить переменную Mutex mutex и после вызова метода вызвать
mutex.Dispose(); ?

P.S. Кому не понятна суть вопроса, подробнее про пустые переменные тут: https://docs.microsoft.com/en-us/dotnet/csharp/discards
    


Ответы

Ответ 1



Сама документация описывает что "пустые переменные" просто ссылаются на некую "пустую" область памяти. То есть не занимают места. Что вряд ли означает что они будут вызывать Dispose() у IDisposable обьектов. Я провел личное расследование даного вопроса и написал прогу для тестирования. Простая винформс апликуха на старте которого вызывается метод: public bool TestMethod(out Image bmp) { Thread.Sleep(3000); bmp = Bitmap.FromFile(@"C:\Users\UKS\Desktop\2000x2000pixels.bmp"); Thread.Sleep(1000); return true; } Выкладываю результаты: public Form1() { InitializeComponent(); Image img; var a = TestMethod(out img); img.Dispose(); } Как видно из картинки - Память возросла и освободилась т.к. мы использовали диспоуз Теперь настал черед теста: public Form1() { InitializeComponent(); var a = TestMethod(out _); } Как видим из картинки - память НЕ освободилась когда я использовал Discard-переменную. Из чего делаем вывод что Дискарды не диспоузят данные. Теперь настал черед еще пары тестов: Конструкция: var a = TestMethod(out _.Dispose()); Не сработает. Говорит что _ не существует в даном контексте. Конструкция: var a = TestMethod(out _); _.Dispose(); Даст ровно тот же результат. Вывод: пустые переменные использовать на IDisposable обьектах категорически нельзя. Итак, самый коректный код в даном конкретном случае есть: Mutex mutex; Boolean existing = Mutex.TryOpenExisting(name: key, rights: MutexRights.ReadPermissions, result: mutex); mutex?.Dispose();//проверяем на null. Если не налл, то вызываем диспоуз.

Комментариев нет:

Отправить комментарий