Хмя, вечная мистика DoEvents ().Было огромное количество негативной реакции, но никто никогда не объяснял, почему это «плохо».Такая же мудрость, как и "не мутируй структуру".Хм, почему среда выполнения и язык поддерживают изменение структуры, если это так плохо?Причина та же: вы стреляете себе в ногу, если не делаете это правильно.Без труда.И чтобы сделать это правильно, нужно знать точно , что он делает, что в случае DoEvents () определенно нелегко.
С самого начала: практически любая программа Windows Forms фактически содержитвызов DoEvents ().Он хитро замаскирован, но с другим именем: ShowDialog ().Именно DoEvents () позволяет диалогу быть модальным, не замораживая остальные окна в приложении.
Большинство программистов хотят использовать DoEvents, чтобы предотвратить зависание их пользовательского интерфейса при написании собственного модального цикла.,Это, безусловно, делает это;он отправляет сообщения Windows и получает любые запросы на рисование.Проблема, однако, в том, что он не избирателен.Он не только отправляет сообщения рисования, он также доставляет все остальное.
И есть набор уведомлений, которые вызывают проблемы.Они приходят примерно с 3 футов перед монитором.Например, пользователь может закрыть главное окно во время работы цикла, который вызывает DoEvents ().Это работает, пользовательский интерфейс исчез.Но ваш код не остановился, он все еще выполняет цикл.Это плохо.Очень, очень плохо.
Есть еще кое-что: пользователь может щелкнуть по тому же пункту меню или кнопке, которая запускает тот же цикл.Теперь у вас есть два вложенных цикла, выполняющих DoEvents (), предыдущий цикл приостановлен, а новый цикл начинается с нуля.Это может сработать, но шансы на это невелики.Особенно, когда вложенный цикл заканчивается, а приостановленный возобновляется, пытаясь завершить работу, которая уже была завершена.Если это не бомбит исключение, тогда, несомненно, данные зашифрованы в ад.
Назад к ShowDialog ().Он выполняет DoEvents (), но обратите внимание, что он делает что-то еще.Он отключает все окна в приложении , кроме диалогового окна.Теперь, когда проблема с 3 футами решена, пользователь не может ничего сделать, чтобы испортить логику.Режимы закрытия окна и запуска задания снова решены.Или, другими словами, пользователь не может заставить вашу программу выполнять код в другом порядке.Он будет выполняться предсказуемо, как и при тестировании кода.Это делает диалоги чрезвычайно раздражающими;кто не ненавидит активный диалог и неспособность копировать и вставлять что-то из другого окна?Но это цена.
Вот что нужно для безопасного использования DoEvents в вашем коде.Установка для свойства Enabled всех ваших форм значения false - это быстрый и эффективный способ избежать проблем.Конечно, ни одному программисту никогда не нравится это делать.И не делает.Вот почему вы не должны использовать DoEvents ().Вы должны использовать темы.Даже при том, что они передают вам полный арсенал способов выстрелить в вашу ногу красочными и непостижимыми способами.Но с тем преимуществом, что вы стреляете только своей ногой;он (как правило) не позволит пользователю стрелять в нее.
В следующих версиях C # и VB.NET будут добавлены новые инструменты с новыми ключевыми словами await и async.В какой-то мере это вызвано проблемами, вызванными DoEvents и потоками, но в значительной степени дизайном API WinRT, который требует , чтобы вы обновляли свой пользовательский интерфейс во время асинхронной операции.Как чтение из файла.