#c_sharp #winforms
Создал вот такой класс: class CursorEx: IDisposable { public CursorEx() { Cursor.Current = Cursors.WaitCursor; } public void Dispose() { Cursor.Current = Cursors.Default; } } Использую вот так: public void Method() { new CursorEx(); //Здаесь что-то выполняется } Подразумевается, что после выполнения метода, вызовется метод Dispose() и курсор установится на дефолтный. Могут ли быть какие-то варианты, когда произойдет сбой?
Ответы
Ответ 1
Во-первых, вы забыли вызвать Dispose. Для этого следует использовать using: using (new CursorEx()) { // что-то выполняется } На сборку мусора полагаться нельзя, она вызывается недетерминированно в любой момент после пропадания объекта из области видимости. Во-вторых, вы не восстанавливаете исходный курсор. Если какая-то функция изменяет курсор, а затем вызывает функцию, которая тоже изменяет курсор, то курсор будет восстановлен уже после возврата из первой функции: using (new CursorEx()) { using (new CursorEx()) { // что-то выполняется } // курсор уже восстановлен } // курсор должен был быть восстановлен здесь Вам следует сохранять текущий курсор в конструкторе и восстанавливать его в Dispose. В-третьих, можно избавиться от лишнего объекта в памяти, если заменить класс на структуру. Итого: public struct CursorWaiter : IDisposable { private readonly Cursor _originalCursor; public CursorWaiter (Cursor newCursor = null) { _originalCursor = Cursor.Current; Cursor.Current = newCursor ?? Cursors.WaitCursor; } public void Dispose () { Cursor.Current = _originalCursor; } } Из комментариев: этот код рассчитан на то, что программист будет использовать тип только с помощью using, не будет уничтожать объект по несколько раз, не будет копировать и т.п. Если есть сомнения в этом, то нужно добавить проверку на повторный вызов Dispose (с помощью отдельного флага или обнуления _originalCursor), а также заменить класс на структуру для избавления он возможности копирования или вовсе скрыть тип за методом с лямбдой.Ответ 2
Конечно. Это вообще хоть раз сработало? Вы неверно пользуетесь сборкой мусора, .NET работает сосвсем не так, как C++. Объект будет уничтожен не в конце метода, а когда захочется сборщику мусора. Поскольку у вас нет на него ссылок, то он может вообще быть уничтожен сразу после создания. А метод Dispose вообще не будет вызван автоматически, IDisposable для рантайма никакого специального значения не имеет. Делайте так: public void Method() { using (new CursorEx()) { //Здаесь что-то выполняется } } И обязательно разберитесь со временем жизни объектов в .NET, без этого никуда.
Комментариев нет:
Отправить комментарий