пятница, 24 сентября 2010 г.

Нетрадиционное использование using и IDisposable

Предположим, что у нас есть форма и на ней кнопка, по нажатию на которую выполняется некая долгоиграющая операция. При выполнении длительных операций в главном потоке приложения, как правило, надо изменить курсор мыши на песочные часы и затем восстановить его. Для этого можно воспользоваться подобным кодом:
private void button1_Click(object sender, EventArgs e){Cursor oldCursor = Cursor.Current;try{Cursor.Current = Cursors.WaitCursor;// do something time consumingDoSomethingTimeConsuming();}finally{Cursor.Current = oldCursor;}}

Хочу обратить внимание, что конструкция try finally необходима, что бы в случае необработанного исключения в DoSomethingTimeConsuming все равно восстановить курсор. Однако у данного обработчика есть несколько недостатков:
  • конструкция достаточно объемна
  • необходимость блока try finally не очевидна и поэтому блок можно забыть.
  • данный код приходится дублировать для каждого подобного обработчика.
У меня есть небольшой трюк, который выполняет ту же работу но не содержит выше перечисленные недостатки. Новый вариант обработчика будет выглядеть следующим образом:
private void button2_Click(object sender, EventArgs e){using (WaitCursor wch = new WaitCursor()){// do something time consumingDoSomethingTimeConsuming();}}
Теперь код обработчика кнопки, по управлению курсором мыши стал намного меньше, а работа по управлению курсором мыши перешла в класс WaitCursor и не будет дублироваться при создании новых обработчиков.
Код для класса WaitCursor:
internal class WaitCursor: IDisposable{private Cursor m_OldCursor;
internal WaitCursor(){m_OldCursor = Cursor.Current;Cursor.Current = Cursors.WaitCursor;}
public void Dispose(){Cursor.Current = m_OldCursor;}}
Использование using приводит к тому что блок try finally будет сгенерирован автоматически. Так же автоматически конструкцией using будет вызван метод WaitCursor. Dispose, который и восстановит курсор.
Хочу отметить, что подобный механизм можно использовать не только для управления курсором

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

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