Application.DoEvents, когда нужно, а когда нет?

StackOverflow https://stackoverflow.com/questions/1115397

  •  12-09-2019
  •  | 
  •  

Вопрос

В чем необходимость использования Application.DoEvents и когда нам следует его использовать?

Это было полезно?

Решение

Application.DoEvents обычно используется для обеспечения периодической обработки событий при выполнении какой-либо длительной операции в потоке пользовательского интерфейса.

Лучшее решение — просто не делать этого.Выполнять длительные операции в отдельных потоках, сортируя их в поток пользовательского интерфейса (либо с помощью Control.BeginInvoke/Invoke или с BackgroundWorker), когда вам нужно обновить пользовательский интерфейс.

Application.DoEvents вводит возможность повторного входа, что может привести к очень трудным для понимания ошибкам.

Другие советы

Windows поддерживает очередь для хранения различных событий, таких как щелчок, изменение размера, закрытие и т. д.Пока элемент управления отвечает на событие, все остальные события остаются в очереди.Поэтому, если вашему приложению требуется слишком много времени для обработки нажатия кнопки, остальная часть приложения может зависнуть.Следовательно, возможно, что ваше приложение не отвечает, пока оно выполняет тяжелую обработку в ответ на событие.Хотя в идеале вам следует выполнять тяжелую обработку асинхронно, чтобы гарантировать, что пользовательский интерфейс не зависает, быстрое и простое решение — просто периодически вызывать Application.DoEvents(), чтобы разрешить отправку ожидающих событий в ваше приложение.

В хорошем Windows-приложении конечному пользователю не нравится, когда какая-либо форма приложения зависает при выполнении более крупных/тяжеловесных операций.Пользователь всегда хочет, чтобы приложение работало плавно и быстро, а не зависал пользовательский интерфейс.Но после поиска в Google я обнаружил, что Application.DoEvents() не рекомендуется использовать в приложении чаще, поэтому вместо этих событий лучше использовать BackGround Worker Thread для выполнения длительной задачи без зависания окон.

Вы можете получить лучшее представление, если посмотрите на практике.Просто скопируйте следующий код и проверьте приложение с добавлением Application.DoEvents() и без него.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For i As Integer = 0 To 1000
            System.Threading.Thread.Sleep(100)
            ListBox1.Items.Add(i.ToString())
            Application.DoEvents()
        Next
    End Sub

Имхо, вам не следует никогда его использовать, так как вы можете получить очень неожиданное поведение.Только что сгенерированный код в порядке.Например, вы снова выполняете обработчик событий, в котором вы сейчас находитесь, потому что пользователь дважды нажал клавишу и т. д. и т. п.Если вы хотите обновить элемент управления для отображения текущего процесса, вам следует явно вызвать .Update для этого элемента управления вместо вызова Application.DoEvents.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top