RaiseEvent Doesn't Trigger Until After Thread Ends

Javin007
Javin007 used Ask the Experts™
on
I'm trying to fire off an event in a thread, and have it update a user interface in the parent thread.  While the code *technically* works, the delay in the event triggers is completely unacceptable.  

I have the following code that spawns the thread in a class that's created "withevents":
        RaiseEvent Lock_On(parTemp.ID, strTemp, intTemp)
        Debug.Print(System.Environment.TickCount & " - 'ON' Event Raised: " & parTemp.ID)
        thrTemp.Start(parTemp)

Open in new window

This event is triggered when the code finishes running:
        RaiseEvent Lock_Off(Params.ID, strTemp, Threads.Unlock(strTemp))
        Debug.Print(System.Environment.TickCount & " - 'OFF' Event Raised: " & Params.ID)

Open in new window


Then in the main class, here are the events:
    Private Sub p1_Lock_On(ByVal Index As Int64, ByVal Name As String, ByVal Thread As Int64) Handles p1.Lock_Off
        Debug.Print(System.Environment.TickCount & " - Received 'ON' Event " & Index)
    End Sub
    Private Sub p1_Lock_Off(ByVal Index As Int64, ByVal Name As String, ByVal Thread As Int64) Handles p1.Lock_Off
        Debug.Print(System.Environment.TickCount & " - Received 'OFF' Event " & Index)
    End Sub

Open in new window


The end result is the following:
     469494609 - 'ON' Event Raised: 1
     469529015 - Received 'OFF' Event 1
     469529015 - Received 'ON' Event 1
     469529062 - 'OFF' Event Raised: 1


As you can see, the "ON" event is being raised, but it's a full 6+ seconds before it's actually RECEIVED by the event handler.  It doesn't actually get received until AFTER the "OFF" event is triggered, either.  Even the raising of the "OFF" event happening AFTER the receiving of the event is somewhat confusing.

Can someone please shed some light on this one?  How do I get the events to trigger WHEN they are actually called?  Otherwise, they're useless.  I may as well just stick all my "on" and "off" code in the same sub and run it at the end of the event.  >:(  Obviously this can be done SOMEHOW since the Debug is getting updated in real-time.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
I don't see any marshalling going on with Invoke/Delegates or using a SynchronizationContext.

Did you turn off "cross-thread checking?"

What version VB.Net are you working in?
To run form or control events from a thread you need to use either BeginInvoke or Invoke.

http://msdn.microsoft.com/en-us/library/ae5kdt95.aspx
Commented:
I presme that's just a typo in you example.... where both event handler's are using p1.Lock_Off
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Good spot graye!  That would be too funny if that was the "root" cause...  =D

The Tick count is the same too:

     469529015 - Received 'OFF' Event 1
     469529015 - Received 'ON' Event 1

Author

Commented:
Sweet... Baby... Jesus...

"I presme that's just a typo in you example.... where both event handler's are using p1.Lock_Off"

Nope, that was not a typo in the code transfer.  That was the glitch.  Do you have ANY idea how many hours I've burned on this, sure there was something mystical that was going on under the hood that I was missing?

Catching that typo in the code just earned you 500 pts.

Will close this without adding it to the knowledge base.  Thanks for the effort, all!
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Buy that man a virtual beer!...

Author

Commented:
ajb2222 / Idle_Mind:

What I do to check for required invocation is the following:


For any method that may require updates that need to be threadsafe (ie: GUI) I declare a delegate:

[Code]     Private Delegate Sub AddLine_Delegate(ByVal Index As Long, ByVal Value As String)[/Code]


Then, at the beginning of these methods, I add this line:
[Code]     Public Sub AddLine(ByVal Index As Long, ByVal Value As String)
        If Me.InvokeRequired Then Me.Invoke(New AddLine_Delegate(AddressOf AddLine), {Index, Value}) : Exit Sub
        'Do Stuff
     End Sub[/Code]

I don't know if this is the "right" way to do it, but it seems to work.  I'm open for suggestions if you know of a more standardized way to do this.

Author

Commented:
Grr.  Code tags didn't work this time.
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
That's perfect!

You can also use a SynchronizationContext or a BackgroundWorker control...
http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_26253934.html

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial