Results 1 to 12 of 12

Thread: [RESOLVED] Raising events on different threads

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Resolved [RESOLVED] Raising events on different threads

    This is related to an early thread I started, but my design and understanding of the problem has changed enough that I figured I'd start something new:

    I have a class that accepts UDP data and puts it in a standardized way into a container class that has been designed to be thread safe. The class that wraps the UDP operations takes the datagrams, packages them into a standardized packaging class, and adds the class to a queue in the receiver class. A different process on a different thread takes items off the queue as it gets the opportunity, or as items arrive.

    This could be done via polling, because I am currently unsure which process will proceed faster. I expect that the UDP thread will be slower, but much more will be happening on the other thread, so it may not read with great frequency.....or maybe it will.

    This poses a bit of a problem for me. If datagrams are received, and the data queued up fast enough that the queue can grow, then polling is a reasonable way to handle data coming in. If, however, the main thread is spending lots of time sitting around waiting for data to arrive in the queue, then polling would prevent an efficient use of that time. I suspect that the latter case will be FAR more typical. Therefore, I think it would be best if the receiver class that wraps the queue raise an event on the main thread when something new is added to the queue. However, the adding will happen on the UDP thread, not the main thread.

    So my question is: What is the best way for an event to be raised on the main thread when something happens in a different thread. I can see one way to do it, but I'm sure it wouldn't be the best way: Have a sub in the receiver class that does nothing but raise the event, and Invoke that sub from the other thread. Alternatively, I could Invoke() a sub that reads from the queue, but that would force the main thread, which is less desirable than just raising an event and letting the main thread do as it pleased with the event.

    EDIT: Slight update on the description of the problem: I had some goofy stuff going on with a Singleton class contained in a Singleton class, so I combined the two into one. Now, the class that holds the UDP thread also holds the queue, but the class itself is a Singleton. When the UDP receiving thread adds something to the queue, the class that contains the UDP thread needs to raise an event on the main thread.
    Last edited by Shaggy Hiker; Jul 2nd, 2007 at 11:10 AM.
    My usual boring signature: Nothing

  2. #2
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: Raising events on different threads

    Could you use a ThreadStart Delegate to call your method? You could put the code from your event into a separate method and have the event and the other thread point to the same method.
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  3. #3

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Raising events on different threads

    Could you expand on that suggestion? Not quite sure what some of the...heck, don't know my grammar, either...things you are talking about are.
    My usual boring signature: Nothing

  4. #4
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: Raising events on different threads

    I used this article to help me with one of my issues.

    http://msdn2.microsoft.com/en-US/lib...rt(VS.80).aspx

    It gives a pretty good example for accessing a static or instace method in another thread. Might be useful in your situation...

    Use the syntax in the example to call a method in your main thread from the UDP thread when data is received. Make sense?
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  5. #5

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Raising events on different threads

    That's a nice link, but it only talks about starting a thread as far as I can see, and it doesn't seem to link to anything else. I have the thread created already, I need to call across threads.
    My usual boring signature: Nothing

  6. #6
    Frenzied Member circuits2's Avatar
    Join Date
    Sep 2006
    Location
    Kansas City, MO
    Posts
    1,027

    Re: Raising events on different threads

    I know there is a way to use some delegate variant or invoke method to call across threads, I just can't remember for the life of me. Hopefully someone else can chime in, otherwise I'll keep looking till I find it.
    Show the love! Click (rate this post) under my name if I was helpful.

    My CodeBank Submissions: How to create a User Control | Move a form between Multiple Monitors (Screens) | Remove the MDI Client Border | Using Report Viewer with Visual Studio 2012 Express

  7. #7

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Raising events on different threads

    Reviving this thread from the dustbin.

    I've been searching around on line, and this question, which has come up in several threads here recently, does not seem to be well answered. It looks like I could possibly set a static reference to the SynchronizationContext.Current in the main thread, then use that to Post to a method in the main thread from the second thread. Not clear whether or not that is the best way to handle this, or even a viable solution. Any comments?
    My usual boring signature: Nothing

  8. #8

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Raising events on different threads

    Well, it does seem to work.
    My usual boring signature: Nothing

  9. #9
    Frenzied Member
    Join Date
    Aug 2006
    Posts
    1,051

    Re: Raising events on different threads

    http://msdn2.microsoft.com/en-us/library/f00zz5b2.aspx

    http://msdn2.microsoft.com/en-us/lib...undworker.aspx

    The handler for the DoWork event runs on the secondary thread.
    The DoWork event is called when the RunWorkerAsync method is called.
    The RunWorkerAsync method can accept any object as an argument.
    The DoWork handler cannot access any controls on the main thread (because it runs on the secondary thread).

    Set the Background worker's ReportsProgress property to True.
    Use the ReportProgress method from inside the DoWork event handler.
    The handler for the ProgressChanged event runs on the main thread. Any object you pass as a parameter to ReportProgress is accessible in the event args of the ProgressChanged event on the mainthread.

    If you want to use the CancelAsync method of the Background worker, it's WorkerSupportsCancellation must be set to true -- else error.
    The code in the DoWork event handler should periodically check the CancellationPending property.

    If you need to perform actions based on the outcome of the DoWork event then write a handler for the RunWorkerCompleted event. The RunWorkerCompleted event can complete on it's own.
    Or you can create a loop in the DoWork event that runs until canceled as in:

    Code:
    Sub DoWork () Handles
    
        Do Until BackGroundWorker.CancellationPending
    
            'Do Things
    
            Backgroundworker.ReportProgress(Object)
    
        Loop
    
    End Sub

  10. #10
    Frenzied Member
    Join Date
    Aug 2006
    Posts
    1,051

    Re: Raising events on different threads

    Oops. Hit reply button instead of Preview.
    Oh, well I'll just leave it at that.
    Maybe that info will help.

  11. #11
    Frenzied Member
    Join Date
    Aug 2006
    Posts
    1,051

    Re: Raising events on different threads

    I was thinking you could create your UDP handling class.
    Pass the UDP handling class as the argument to the new thread.
    Your UDP class would SyncLock itself before modifying the que (I hope a class can synclock itself). The worker thread then calls the main thread with an update. The main class responds to the update and SyncLocks the UDP class while reading it's que or modifying any of the UDP class data.
    Then release the lock.

  12. #12

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Raising events on different threads

    Actually, I have a workable solution with the SynchronizationContext, so I started a new thread asking about why it is working (because SynchronizationContexts are really poorly explained), and got a link to a good explanation. Therefore, I think I have about the most effective solution I could ask for, and shall designate this thread as resolved.
    My usual boring signature: Nothing

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