Results 1 to 13 of 13

Thread: Passing values between threads *Resolved*

  1. #1

    Thread Starter
    KING BODWAD XXI BodwadUK's Avatar
    Join Date
    Aug 2002
    Location
    Nottingham
    Posts
    2,176

    Passing values between threads *Resolved*

    Hello everyone, I am an old VB6 programmer and I am trying to get into vb.net but having an issue getting a variable value from a class library in a different thread.

    What I am trying to do is create my own Winsock type control for my own use. Once data arrives I try and pass it back to the main application so that I can read it and process it.

    So far I cant get it working at all. I have tried the following

    Raiseevent
    I try passing the value as a variable in the raiseevent property. This triggers an error about the value being in a different thread, I always thought that it would create a new variable in the thread of the application it was raising an event in and copy the value.

    Function
    I have tried writing a function into the class that I call (much like how the winsock control works) so that the class can return the value to the main application.

    aka
    strData = Myclass.GetData

    in the class it returns the value and clears it from its own local variable. This however means the value returns to the main application as nothing even if I step through and see it assigning a value.

    I have to be missing something really important. Coming from a VB6 background I dont really know where to begin.

    Any help or pointers would be appreciated

    Thanks
    Last edited by BodwadUK; Oct 28th, 2009 at 06:18 AM.
    If you dribble then you are as mad as me

    Lost World Creations Website (XBOX Indie games)
    Lene Marlin

  2. #2
    Addicted Member
    Join Date
    Oct 2009
    Posts
    212

    Re: Passing values between threads

    Maybe I'm missing something here... You would need to create a delegate and invoke it (others will correct me if I'm wrong I'm sure)
    Last edited by 7777; Oct 26th, 2009 at 05:00 AM.

  3. #3
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Passing values between threads

    but having an issue getting a variable value from a class library in a different thread.
    What makes you think it is running in a different thread? Have you explicitly created a new thread in this class library?
    Can you post the code you are using in your function (Myclass.GetData) and also the code around the part in your main application where you use this function?

    PS if it is a threading issue, search for "worker threads" in the codebank on this forum and you will find a post from JMC that explains how to use delegates to invoke code on another thread
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  4. #4

    Thread Starter
    KING BODWAD XXI BodwadUK's Avatar
    Join Date
    Aug 2002
    Location
    Nottingham
    Posts
    2,176

    Re: Passing values between threads

    Hello, decided it was easier to post the whole project. I dont mind other people seeing it just bare in mind I still work with vb6 so my logic might be odd for vb.net

    I assume its running in a different thread as I am writing it in a seperate project thats referanced from the main project. This is because I will need to use it in many different projects in the future. i also assumed its a different thread because of the error I got about not being able to cross the thread (Never ever cross the streams remember )

    Thanks, I will look at that invoke threads stuff and see if I can get it working
    Attached Files Attached Files
    If you dribble then you are as mad as me

    Lost World Creations Website (XBOX Indie games)
    Lene Marlin

  5. #5
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Passing values between threads

    OK well you have only uploaded the socket component you are making, not the actual application as well so I cant see how you are using your socket component or which function it is that you are having a problem with etc.

    PS, just because something is in a different class library / project does NOT mean it is running in a different thread. The only time something runs in a different thread is if you either create a new Thread object and start your code via that, or if you use a method that uses multiple threads - I suspect the latter may be the case here as I notice you are using BeginConnect and BeginAccept etc, which are asynchronous methods.

    EDIT: Also, do you know that JMC already made something like this just a few weeks ago? http://www.vbforums.com/showthread.php?t=587341
    Last edited by chris128; Oct 26th, 2009 at 05:49 AM.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  6. #6
    Addicted Member
    Join Date
    Oct 2009
    Posts
    212

    Re: Passing values between threads

    Something like this...
    Code:
    Line 20 Public Event DataArrived(byVal DataPacket As String)
    Line 173 RaiseEvent DataArrived(DataPacket)
    To use it
    Code:
    Private WithEvents listener As SLSock
    Private Sub listener_DataArrived(byVal DataPacket As String) Handles listener.DataArrived
    MessageBox.Show("Data Packet:" & DataPacket )
    End Sub

  7. #7

    Thread Starter
    KING BODWAD XXI BodwadUK's Avatar
    Join Date
    Aug 2002
    Location
    Nottingham
    Posts
    2,176

    Re: Passing values between threads

    Bah sorry I must have the test program in a different folder. I will have a look at JMC's project and see if I can make sense of it. Thankyou
    If you dribble then you are as mad as me

    Lost World Creations Website (XBOX Indie games)
    Lene Marlin

  8. #8

    Thread Starter
    KING BODWAD XXI BodwadUK's Avatar
    Join Date
    Aug 2002
    Location
    Nottingham
    Posts
    2,176

    Re: Passing values between threads

    Hi thanks 7777, thats what I tried to start with. The value gets passed in the event fine but I see now that the error occurs when I try to show the value in a text box on the form.

    Is this where I should use the invoke command to display it in the textbox? I am struggling to understand why its in a different thread though as I thought the raiseevent would raise it in the thread of the application receiving the event (if that makes sense S)

    It seems I have a lot to learn lol


    I get this error on this raised event
    Cross-thread operation not valid: Control 'txtServer' accessed from a thread other than the thread it was created on.

    Code:
    Private Sub tcpServer_DataArrived(ByVal strData As String) Handles tcpServer.DataArrived
            'Send follow up command
            tcpServer.SendData("Hello Client")
    
            'Show the data
            txtServer.Text = strData
    
        End Sub
    If you dribble then you are as mad as me

    Lost World Creations Website (XBOX Indie games)
    Lene Marlin

  9. #9
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Passing values between threads

    No, RaiseEvent will raise the event in the thread that you call RaiseEvent in, not the thread that is handling the event. If you happen to handle that event on another thread then you need to invoke a delegate to execute the code on the correct thread.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing values between threads

    When you call RaiseEvent, the event is raised on the same thread and the event handlers are executed on the same thread. That means that if you call RaiseEvent on a secondary thread the event will be raised on that secondary thread and the event handlers will be executed on that secondary thread. As such, if you need to access controls from your event handler, you have two choices:

    1. Marshal a method call to the UI thread first, then call RaiseEvent from that method.

    2. Call RaiseEvent first, then marshal a method call to the UI thread in the event handler.

    If you choose the first option then the objects handling the event, e.g. your form, need not even be aware that there was a secondary thread involved at all. If you choose the second option then the handling object must be aware of the multi-threading and account for it.

    To marshal a method call from one thread to another, you have basically two choices: the ISynchronizeInvoke interface or the SynchronizationContext class. Despite the fact that many may not recognise the name, the ISynchronizeInvoke interface is the most familiar to most people. When we use the InvokeRequired property and Invoke or BeginInvoke methods of a control, that's actually an ISynchronizeInvoke implementation. For examples and an explanation of why and how to use the ISynchronizeInvoke interface to access controls from a secondary thread, follow the CodeBank link in my signature and find my Accessing Controls From Worker Threads submission. If you wanted raise events on a secondary thread and then marshal a method call to the UI thread in the event handler, that will show you how.

    Examples of using the ISynchronizeInvoke interface before calling RaiseEvent, therefore raising the event on the UI thread, include the FileSystemWatcher and Timers.Timer classes. They both have a SynchronizingObject property of type ISynchronizeInvoke. If this property is not set then those classes will raise their events on background threads from the thread pool. If you assign a control to the property though, the events will be raised on the thread that owns that control's handle, using its ISynchronizeInvoke implementation. In that Asynchronous Client/Server submission of mine that chris128 mentioned, that's the approach that I took to begine with. I declared a SynchronisingObject property in my classes and, if set, it was used internally to marshal a call to the desired thread before calling RaiseEvent. I can post that version of the code here if you want to see it.

    The reason that I would have to post it here is that I've replaced the attachment in that submission with a new version that uses the SynchronizationContext class. The SynchronisingObject property has been removed and all events are always raised on the same thread as the object was created on. You can check out the attachment in that submission to see how that works.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11
    Addicted Member
    Join Date
    Oct 2009
    Posts
    212

    Re: Passing values between threads

    Here is a simple example of method # 2 as described above (you'll need to tweak it for your code of course). I would like to see an example of method # 1
    Code:
    Delegate Sub UpdateTextCallBack(ByVal vData As String)
        Private Sub UpdateText(ByVal vData As String)
            Try
                If Me.TextBox2.InvokeRequired Then
                    Dim d As New UpdateTextCallBack(AddressOf UpdateText)
                    Me.Invoke(d, New Object() {vData})
                Else
                    TextBox2.Text = vData
                End If
            Catch ex As Exception
            End Try
        End Sub

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing values between threads

    Quote Originally Posted by 7777 View Post
    I would like to see an example of method # 1
    This is basically how I originally did it in my Async Client/Server:
    vb.net Code:
    1. Imports System.ComponentModel
    2.  
    3. Public Class EventRaiser
    4.  
    5.     Private Delegate Sub EventRaiserInvoker(ByVal e As EventArgs)
    6.  
    7.     Private _synchronisingObject As ISynchronizeInvoke
    8.  
    9.     Public Property SynchronisingObject() As isynchronizeinvoke
    10.         Get
    11.             Return _synchronisingObject
    12.         End Get
    13.         Set(ByVal value As isynchronizeinvoke)
    14.             _synchronisingObject = value
    15.         End Set
    16.     End Property
    17.  
    18.     Public Event SomeEvent As EventHandler
    19.  
    20.     Protected Overridable Sub OnSomeEvent(ByVal e As EventArgs)
    21.         If Me._synchronisingObject IsNot Nothing AndAlso _
    22.            Me._synchronisingObject.InvokeRequired Then
    23.             Me._synchronisingObject.Invoke(New EventRaiserInvoker(AddressOf OnSomeEvent), _
    24.                                            New Object() {e})
    25.         Else
    26.             RaiseEvent SomeEvent(Me, e)
    27.         End If
    28.     End Sub
    29.  
    30. End Class
    You would simply raise the event exactly as you would without the multi-threading support:
    vb.net Code:
    1. Me.OnSomeEvent(EventArgs.Empty)
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  13. #13

    Thread Starter
    KING BODWAD XXI BodwadUK's Avatar
    Join Date
    Aug 2002
    Location
    Nottingham
    Posts
    2,176

    Re: Passing values between threads

    Hello, sorry about the late response been ill yesterday.

    I have managed to get it working using the first method, I also now understand how it works which is great, before I was a little confused as to how it was executed etc but writting it into my application has made it much more clear.

    Thanks for you help everyone
    If you dribble then you are as mad as me

    Lost World Creations Website (XBOX Indie games)
    Lene Marlin

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