-
Apr 10th, 2014, 03:36 PM
#1
[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.
-
Apr 10th, 2014, 03:56 PM
#2
Re: Stop MethodInvoker
The solution was simple, I just aborted the thread.
-
Apr 11th, 2014, 02:53 PM
#3
Re: Stop MethodInvoker
Originally Posted by dday9
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...
-
Apr 11th, 2014, 03:04 PM
#4
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?
-
Apr 11th, 2014, 03:27 PM
#5
Re: [RESOLVED] Stop MethodInvoker
Why would you abort a thread in form closing? IsBackGround = True
-
Apr 11th, 2014, 04:05 PM
#6
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.
-
Apr 11th, 2014, 05:29 PM
#7
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).
-
Apr 11th, 2014, 06:03 PM
#8
Re: [RESOLVED] Stop MethodInvoker
-
Apr 12th, 2014, 07:54 AM
#9
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|