-
May 15th, 2007, 04:24 PM
#1
Forms Timer and Thread problem
Hi,
I have an application which contains a form with a Forms.Timer. For some reason, the tick event is not getting called... Somehow this is connected to the fact that I start a new thread...
Here are some code snippets.
Code:
Private Sub tmrSchedule_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrSchedule.Tick
Dim processor As New EDIProcessor
AddHandler processor.ProcessingComplete, AddressOf EDIProcessor_ProcessingComplete
If tmrSchedule.Enabled Then tmrSchedule.Stop()
ediWorker = New Thread(AddressOf processor.Run)
ediWorker.Start()
last = 0
'Call Me.EDIProcessor_ProcessingComplete("")
End Sub
Public Sub EDIProcessor_ProcessingComplete(ByVal msg As String)
'Do we need to somehow remove handlers here?
lstInfo.Items.Add("Process Complete " & msg)
Call scroll()
tmrSchedule.Enabled = True
tmrSchedule.Start()
pnlTransaction.Text = ""
End Sub
I disable the timer in the timer tick and enable it again when the processing is complete. I don't understand it, but the timer never fires after that, even though tmrSchedule.Enabled = true, and the interval is set to 20000, so it should be called again 20 seconds after the thread calls the Processing_Complete Event. Processing_Complete event is fired, and everything executes, but tmrSchedule.Tick is never fired again.
tmrSchedule is a Forms timer and not a threading timer. Also, I commented out the creation and starting of the thread, and the timer worked... I do not reference the timer in any other code in the application...
Any clues on why this would happen?
Thanks,
Ranthalion
-
May 15th, 2007, 10:07 PM
#2
Re: Forms Timer and Thread problem
you have to use the form invoke method to start the timer from EDIProcessor_ProcessingComplete sub.
ex.
me.invoke(new methodinvoker(addressof tmrSchedule.Start()))
Busy
-
May 16th, 2007, 07:11 AM
#3
Re: Forms Timer and Thread problem
Thanks! That works. I don't understand why it is different from what I had, or why invoke is needed instead of just enabling, or starting, the timer by itself. Do you know of any sites where I can get more information on this kind of problem?
(The Processing_Complete Event is thrown from a different thread, but it is caught by the forms thread isn't it? So this isn't a case of a cross thread issue, is it?)
Thanks,
Ranthalion
-
May 16th, 2007, 11:23 AM
#4
Re: Forms Timer and Thread problem
>The Processing_Complete Event is thrown from a different thread, but it is caught by the forms thread isn't it?
Nope, the event handler runs on the same thread as it was thrown. You can prove this to yourself by giving the thread a name and checking the current threads name in the event handler.
-
May 16th, 2007, 02:44 PM
#5
Re: Forms Timer and Thread problem
Ok, so now that I understand this a little better, I have rewritten some of the code. The problem is that it just seems wrong, like I'm missing something obvious...
Here's what I have now...
Code:
Private Sub EDIScheduler_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Thread.CurrentThread.Name = "GUI"
End Sub
Private Sub tmrSchedule_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrSchedule.Tick
Dim processor As New EDIProcessor
AddHandler processor.RunningJob, AddressOf EDIProcessor_RunningJob
AddHandler processor.ProcessingComplete, AddressOf EDIProcessor_ProcessingComplete
If tmrSchedule.Enabled Then tmrSchedule.Stop()
ediWorker = New Thread(AddressOf processor.Run)
ediWorker.Name = "ediWorker"
ediWorker.Start()
last = 0
End Sub
Public Sub EDIProcessor_ProcessingComplete(ByVal msg As String)
If (ediWorker.Name = Thread.CurrentThread.Name) Then
Me.Invoke(New EventDelegate(AddressOf EDIProcessor_ProcessingComplete), New Object() {msg})
Else
'Do we need to somehow remove handlers here?
lstInfo.Items.Add("Process Complete " & msg)
Call scroll()
Me.Invoke(New MethodInvoker(AddressOf tmrSchedule.Start))
'tmrSchedule.Enabled = True
'tmrSchedule.Start()
pnlTransaction.Text = ""
End If
End Sub
So, basically, I'm naming my GUI thread (because otherwise it didn't have a name...) and my worker thread. Then, in the event handler, I'm checking the names, and invoking the handler again if I'm not on the GUI thread... Is this the wrong way to do it?
On a side note: I hook up multiple event handlers in the timer tick event. Should I remove those handlers in the ProcessingComplete event, or is that unnecessary? (or would it cause problems...)
[Edit: Ok, so I found InvokeRequired, and I can use that, but it doesn't really change the situation of having to check it on every event handler....]
Thanks,
Ranthalion
Last edited by Ranthalion; May 16th, 2007 at 03:07 PM.
Reason: New Info
-
May 16th, 2007, 09:50 PM
#6
Re: Forms Timer and Thread problem
as we know since the object was hosted onto a separate thread all of its events also will run on that thread. the remarks in the InvokeRequired at msdn explains why you have to call the timer control this way.. there is no need to check the thread name and there is no need to remove the handlers in the EDIProcessor_ProcessingComplete sub as the object was instantiated per timer event, it will be disposed off automatically.
Code:
Public Sub EDIProcessor_ProcessingComplete(ByVal msg As String)
' If (ediWorker.Name = Thread.CurrentThread.Name) Then
' Me.Invoke(New EventDelegate(AddressOf EDIProcessor_ProcessingComplete), New Object() {msg})
' Else
'Do we need to somehow remove handlers here?
lstInfo.Items.Add("Process Complete " & msg)
Call scroll()
Me.Invoke(New MethodInvoker(AddressOf tmrSchedule.Start))
'tmrSchedule.Enabled = True
'tmrSchedule.Start()
pnlTransaction.Text = ""
' End If
End Sub
Busy
-
May 17th, 2007, 09:22 AM
#7
Re: Forms Timer and Thread problem
>there is no need to check the thread name
Correct. My suggestion about naming the threads was simply for debugging purposes so you can see what's going on. InvokeRequired is how you should check in code during runtime.
-
May 17th, 2007, 03:24 PM
#8
Re: Forms Timer and Thread problem
Thanks DSJ and Thread1! That set me off on my journey to learn more about threading... It seems like I should have designed the EDIProcessor class to work a little differently and handle the multithreading itself, instead of the way I did it... I'm off to the bookstore today to look for a book on mulithreaded programming then.
Thanks again!
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
|