Sam1996
Sam1996

Reputation: 35

Exit 2 for loops pressing esc button

I am using vb.net to code. This program goes through each pixel in a picturebox checking and compare the color that the user selected. I made a code to stop the looping when the user press ESC button on the keyboard. But it looks like the program does not stop when the the esc is pressed.

I made a messagebox to pop when the esc button is pressed. When the loop is running and I press the esc button, the messagebox pops up only when the whole loop is done.

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

Any help I would be thankful.

Upvotes: 0

Views: 1003

Answers (2)

djv
djv

Reputation: 15774

Here are a couple options. Both have the processing code run off the UI thread. The first uses a Thread as you suggested, but with the syntax to get you going. Code execution continues after Thread.Start is called. The second uses Async/Await which doesn't create an additional thread but still takes the processing off the UI. This is a more modern approach. Both should work for you. Instead of using your exact code, this just counts to 100 over 10 seconds.

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

It seems like the condition

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

is needless since that will never change unless the PictureBox width is changing mid-loop. This could be checked once prior to the loop, or could be checked prior to calling checkColor, which is where it should be done since you're interacting with UI, and why make a pointless call for nothing?

Upvotes: 2

Ess Kay
Ess Kay

Reputation: 598

Since you have a single thread, the button function will not fire until the loops have ended.

You can confirm this by making x and y global integers, and displaying them in the messagebox.

If you want to be able to exit, you will need to create a second thread, and run the loops on that thread.

An example for multithreading can be found here: http://howtostartprogramming.com/vb-net/vb-net-tutorial-53-multithreading/

Upvotes: 1

Related Questions