Button Interrupt Problem

jbrookley

Member
Joined
Jan 8, 2009
Messages
11
Programming Experience
1-3
Hello.

So, I have an event I want to do continuously until a button interrupt is pressed.

Here's the pseudocode:

VB.NET:
Click button 1:
     Check if button 2 is pressed
          If not, do stuff
          If so, stop doing stuff
End routine

So what I currently have is this:

VB.NET:
Dim randominteger As Integer = 0

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartSampleButton.Click
        While 1
            If randominteger = 0 Then

                 'Do Stuff Here

            ElseIf randominteger = 1 Then
                Exit While
            End If
        End While
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TakeSampleButton.Click
        randominteger = 1
End Sub

Unfortunately, it's never breaking outside of the first loop. Any ideas why or suggestions as of how to get around it? Thanks!
 
2 things, there is no way to check if a button is pressed, when it's clicked it's click event fires. The second is if you're doing that loop in the UI thread then of course none of the other action's are going to be performed. What you could do is have the loop code run on a background thread using the BackgroundWorker control and if you want to terminate it early (interrupt it) you could have it check a boolean variable and you simply set it that variable to false and the loop will end early.
 
Heh, sadly, I somehow managed to make it work. It just wasn't allowing any background events to occur so it wasn't registering that I was clicking the button. But yeah, I just added in Application.DoEvents() and everything seemed to work out.

VB.NET:
Dim randominteger As Integer = 0

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartSampleButton.Click
        While 1
            If randominteger = 0 Then

                 'Do Stuff Here
                 Application.DoEvents()

            ElseIf randominteger = 1 Then
                Exit While
            End If
        End While
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TakeSampleButton.Click
        randominteger = 1
End Sub

Kind of a sloppy solution but it works, I guess. Thanks for your help!

If you still think it's worth reexamining the way I did it, let me know. For now though, I'm just happy that I'm able to get anything to work, being a hardware guy and all . . . heh.

Thanks again.
 
Personally I think the Application.DoEvents is more of a hack instead of a solution. What the Application.DoEvents does is it pauses the currently running code and allows the everything in the events queue to be processed. So if the current thread is tying up the CPU and the user clicks a button on the form, when the loop hits the Application.DoEvents line that button click will be processed, which might be a split second after they click it, or depending on how intense the processing is and where the Application.DoEvents is placed (or how often it's placed) it might be a minute or two before that click event gets processed.

That's why I think it's more of a hack than a solution. If the loop code were running on a background thread, then regardless how intense the processing is, their button click gets processed immediately. That and your app's guaranteed to not get the 'Application not responding" notice in the title bar even though it's running fine.
 
Hmm. That does sound like a more elegant solution. What are the chances you know of a good tutorial or code example that is easy to follow? Like I said, I'm a hardware guy so I'm just winging this thing . . .
 
Alright guys, I'm getting closer.

I've been following this example, which is pretty similar to what I'm trying to do:

Understanding the BackgroundWorker Component - O'Reilly Media

My problem right now has to do with trying to store a value in the RealTimeSample while in the background worker portion. I'm getting the error:

"Cross-thread operation not valid: Control 'RealTimeSample' accessed from a thread other than the thread it was created on."

in the TakeSample function on this line:

VB.NET:
RealTimeSample.Text = ioDmm.ReadNumber

From what I understand, there might be a way to get around this using the invoke command. I've been reading from here:

How to: Make Thread-Safe Calls to Windows Forms Controls

but can't seem to get it to work correctly on my computer (it doesn't recognize anything pertaining to the "Me.*****". Not sure if I need to import some namespace to use the "Me." commands. Can you guys help me or suggest some code that might work to fix this? I think I'm getting pretty close. Below is the code relevant to this application:


VB.NET:
    Private Sub StartSampleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartSampleButton.Click

        BackgroundWorker1.RunWorkerAsync(103)

    End Sub

    Private Sub TakeSampleButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TakeSampleButton.Click
        Dim temp As Decimal = RealTimeSample.Text
        TakenSample.Text = Math.Round(temp, 3)

        BackgroundWorker1.CancelAsync()
    End Sub

   Function TakeSample( _
    ByVal channel As Integer, _
    ByVal worker As System.ComponentModel.BackgroundWorker, _
    ByVal e As DoWorkEventArgs) As Double

        If worker.CancellationPending = True Then
            e.Cancel = True
        Else
            ioDmm.WriteString("MEAS:VOLT:DC? AUTO,DEF,(@" & channel & ")")
            RealTimeSample.Text = ioDmm.ReadNumber
            RealTimeSample.Refresh()
            System.Threading.Thread.Sleep(200)
        End If
    End Function

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As System.ComponentModel.BackgroundWorker = _
        CType(sender, System.ComponentModel.BackgroundWorker)
        e.Result = TakeSample(CType(e.Argument, Integer), worker, e)
    End Sub
End Class

Thanks for all your help!
 
Back
Top