Выход 2 для петель, нажав кнопку Esc - PullRequest
0 голосов
/ 30 сентября 2019

Я использую vb.net для кодирования. Эта программа проверяет каждый пиксель в картинке и сравнивает выбранный пользователем цвет. Я сделал код, чтобы остановить цикл, когда пользователь нажимает кнопку ESC на клавиатуре. Но похоже, что программа не останавливается при нажатии клавиши esc.

Я сделал сообщение для всплывающего окна при нажатии кнопки esc. Когда цикл работает, и я нажимаю кнопку esc, окно сообщений появляется только после завершения всего цикла.

For x = rect.X To endPointX - 1 Step pixelStep
    For y = endpointY - 1 To rect.Y Step -1

        If e.X >= 0 And e.Y >= 0 And (e.X < PictureBox1.Width) And (e.Y < PictureBox1.Height) Then
            If escPress  Then
                Exit For
            End If

            If bmp.GetPixel(x, y) = cor Then
                cruzNoBitmap(PictureBox1, n, pemSize, x, y)

                addRow(x, y)
                Exit For
            End If
        End If
    Next

    If escPress Then
        Exit For
    End If
Next
Private Sub frmBitmaps_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        If  e.KeyCode = Keys.Escape Then
            MsgBox("test")
            escPress = True
        End If
End Sub

Любая помощь, я был бы благодарен.

Ответы [ 2 ]

2 голосов
/ 01 октября 2019

Вот пара вариантов. У обоих код обработки запускается из потока пользовательского интерфейса. Первый использует Thread, как вы предложили, но с синтаксисом, чтобы начать работу. Выполнение кода продолжается после вызова Thread.Start. Второй использует Async/Await, который не создает дополнительный поток, но все же снимает обработку с пользовательского интерфейса. Это более современный подход. Оба должны работать на вас. Вместо того, чтобы использовать ваш точный код, это всего лишь 100 в течение 10 секунд.

Private escPress As Boolean = False

Private Sub RunThreadButton_Click(sender As Object, ea As EventArgs) Handles runThreadButton.Click
    Dim p As New Point()
    Dim thread2 = New System.Threading.Thread(Sub() checkColor(p))
    thread2.Start()
End Sub

Private Async Sub AsyncButton_Click(sender As Object, e As EventArgs) Handles asyncButton.Click
    Dim p As New Point()
    Await Task.Factory.StartNew(Sub() checkColor(p))
End Sub

Private Sub EscapeButton_Click(sender As Object, e As EventArgs) Handles escapeButton.Click
    escPress = True
End Sub

Private Sub checkColor(e As Point)
    Try
        For x = 0 To 9
            If escPress Then Exit For
            For y = 0 To 9
                If escPress Then Exit For
                Threading.Thread.Sleep(100)
                Console.WriteLine(y + 10 * x + 1)
            Next
        Next
    Finally
        escPress = False
    End Try
End Sub

Кажется, что условие

If e.X >= 0 And e.Y >= 0 And (e.X < PictureBox1.Width) And (e.Y < PictureBox1.Height) Then

не нужно, поскольку оно никогда не изменится, если только ширина PictureBoxменяется в середине цикла. Это может быть проверено один раз перед циклом, или может быть проверено перед вызовом checkColor, где это должно быть сделано, так как вы взаимодействуете с пользовательским интерфейсом, и зачем делать бессмысленный вызов напрасно?

1 голос
/ 30 сентября 2019

Поскольку у вас есть одиночный поток, функция кнопки не будет срабатывать до тех пор, пока не завершатся циклы.

Это можно подтвердить, сделав глобальные целые числа x и y и отобразив их вокно сообщения.

Если вы хотите иметь возможность выйти, вам нужно создать второй поток и запустить циклы в этом потоке.

Пример многопоточности можно найти здесь:http://howtostartprogramming.com/vb-net/vb-net-tutorial-53-multithreading/

...