Results 1 to 9 of 9

Thread: [RESOLVED] Stop MethodInvoker

  1. #1

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Resolved [RESOLVED] Stop MethodInvoker

    I'm working on improving a game that I made called bouncy ball. One thing I'm doing is wrapping everything in a managed game loop and bringing operations to their own thread. One issue that I'm having though is I'm using this to move a control on a separate thread:
    Code:
    Private Sub MoveBall()
        player.Left += player.HorizontalMove
        player.Top += player.VerticalMove
    End Sub
    
    Private Sub ThreadMoveBall()
        If player.InvokeRequired Then
            player.Invoke(New MethodInvoker(AddressOf ThreadMoveBall))
        Else
            Me.MoveBall()
        End If
    End Sub
    But if the user closes out of the game while the game is still playing then I receive an error:
    System.InvalidOperationException was unhandled
    Message=Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
    On the like where I invoke the control. I currently have a Boolean value named quit to check if the game is running or not and I've tried expanding my conditional statement to this:
    Code:
    If player.InvokeRequired AndAlso quit = False Then
    And setting quit to True in the Form's closing event, but even that isn't working. I'm at a loss here.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  2. #2

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Re: Stop MethodInvoker

    The solution was simple, I just aborted the thread.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  3. #3
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,398

    Re: Stop MethodInvoker

    Quote Originally Posted by dday9 View Post
    The solution was simple, I just aborted the thread.
    Nooooooo, Never ever use abort. It's a "the world is on fire what else can we do". Aborting a thread is not safe, and this behavior is intentional. It's dangerous and can leave data in a corrupt state. Do you just pull your pcs plug out when shutting down...

  4. #4

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Re: [RESOLVED] Stop MethodInvoker

    Do you just pull your pcs plug out when shutting down...
    Sometimes nah I'm joking. But this was what I wound up using only because it works:
    Code:
    quit = True
    If gameThread IsNot Nothing Then
        gameThread.Abort()
    End If
    And that's in the FormClosing event. How else should I do it?
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  5. #5
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,398

    Re: [RESOLVED] Stop MethodInvoker

    Why would you abort a thread in form closing? IsBackGround = True

  6. #6

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Re: [RESOLVED] Stop MethodInvoker

    My game loop is on a separate thread called gameThread and if the user closes the application during gameplay then I get an error because the game loop will still run.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  7. #7

    Thread Starter
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Re: [RESOLVED] Stop MethodInvoker

    If you want to see the code in action, take a look at my Bouncy Ball game(more specifically the last update).
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  8. #8

  9. #9
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: [RESOLVED] Stop MethodInvoker

    I agree with ident, use IsBackGround and do NOT use .Abort. When I write code that uses threads I use the following pattern. It creates a structure that contains the thread and a flag(ManualResetEvent) for the thread. The flag serves two purposes. It provides a means for the thread to be told to stop, and it can be used to sleep the thread.

    Because I like to know exactly how the thread ends when the app is closed, the FormClosing event doesn't actually close the first time it is called. Instead it starts another thread that causes the other threads to end, and then it closes the app.

    To see how this works create a new form and paste the code.

    Code:
    Public Class Form1
    
        Structure bkgThrd
            Public thrd As Threading.Thread
            Public isStop As Threading.ManualResetEvent
        End Structure
    
        Dim bkgThrds As New List(Of bkgThrd)
        Dim isRun As New Threading.ManualResetEvent(True)
    
        Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
            Dim foo As New bkgThrd 'setup the thread to start
            foo.isStop = New Threading.ManualResetEvent(False) 'a controlling object for the thread
            foo.thrd = New Threading.Thread(AddressOf gameThread)
            foo.thrd.IsBackground = True
            bkgThrds.Add(foo) 'add to list
            foo.thrd.Start(foo) 'start the thread
        End Sub
    
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            If isRun.WaitOne(0) Then 'running
                isRun.Reset() 'yes, reset run
                'start helper
                Dim fc As New Threading.Thread(AddressOf FormClosingHelper)
                fc.IsBackground = True
                fc.Start()
                e.Cancel = True 'cancel this close
            End If
        End Sub
    
        Private Sub FormClosingHelper()
            'stop threads that are running
            For Each bt As bkgThrd In bkgThrds
                bt.isStop.Set()
                bt.thrd.Join()
            Next
            'close 
            Me.BeginInvoke(Sub()
                               Me.Close()
                           End Sub)
        End Sub
    
        Private Sub gameThread(Ctlr As Object)
            Dim myCtrl As bkgThrd = DirectCast(Ctlr, bkgThrd)
            Do
                'the loop
                Debug.WriteLine("*")
                'note that the isStop can be used to sleep the thread
            Loop While Not myCtrl.isStop.WaitOne(1000)
        End Sub
    End Class
    Last edited by dbasnett; Apr 12th, 2014 at 07:59 AM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width