DoEvents
Когда вы в предыдущем примере безрезультатно щелкали мышкой по второй кнопке, ваши щелчки все же не пропали бесследно. Они запомнились и встали в очередь на обработку. Вы можете удостовериться в этом, задав в первой процедуре не бесконечный цикл, а конечный, секунд эдак на 10. Пока он выполняется, щелкните по второй кнопке. Она, конечно, не среагирует. Спокойно ждите, пока цикл не кончится. Когда он завершится, тут же само собой начнется выполнение второй процедуры. Значит, щелчок не пропал.
Дополните ваш проект двумя текстовыми полями, а каждую из двух процедур – двумя строками. Строки же печати в окно Output уберите:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer = 1
Do
TextBox1.Text = i
i += 1
Application.DoEvents()
Loop
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim i As Integer = 1
Do
TextBox2.Text = i
i += 1
Application.DoEvents()
Loop
End Sub
Теперь числа побегут не в окне Output, а в текстовых полях.
Вы видите, что на каждой итерации цикла будет выполняться метод DoEvents класса Application пространства имен System.Windows.Forms. Этот метод приказывает обработать все события, стоящие к этому моменту в очереди. Это решает дело. Поскольку цикл работает очень быстро, этот метод будет выполняться много раз в секунду, поэтому, стоит нам нажать на какую-нибудь кнопку, как тут же это нажатие будет обработано.
Проверим. Запустите проект. Щелкните по кнопке 1. В текстовом поле 1 побегут числа. Теперь нажмите один-два раза кнопку 2. Числа теперь побегут в текстовом поле 2, а в текстовом поле 1 остановятся. Снова щелкните по кнопке 1. Числа в текстовом поле 2 остановятся, а в текстовом поле 1 снова начнут бежать.
Обратите внимание, что бежать они начнут, но не с того места, где остановились, а начиная с 1. Значит, получается, что по приказу метода DoEvents управление «выпархивает» из процедуры-обработчика, и больше уж в точку «вылета», как мы привыкли, не возвращается. В следующий раз, если оно попадает в этот обработчик, то только законным путем (в нашем случае при новом нажатии кнопки 1, когда начинает с самого начала работать процедура 1). Одновременно обе процедуры работать не могут.
Таким образом, проблему мы решили, но решили частично. Если какая-то процедура работает слишком долго, мы можем ее прервать, но потом-то, если она не доделала что-то нужное, все равно придется ее запускать.