Results 1 to 7 of 7

Thread: Passing Data to a Thread Entry Method

  1. #1

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Passing Data to a Thread Entry Method

    C# version here.

    Originally there was no way to pass data directly to a method that you were using as the entry point for a thread. You had to assign your data to one or more member variables and then retrieve it again in the new thread.
    vb.net Code:
    1. Private data As Integer
    2.  
    3. Private Sub InitiateThread()
    4.     Me.data = 100
    5.  
    6.     Dim t As New Thread(AddressOf DoWork)
    7.  
    8.     t.Start()
    9. End Sub
    10.  
    11. Private Sub DoWork()
    12.     Dim data As Integer = Me.data
    13.  
    14.     'Use data here.
    15. End Sub
    Many developers would create classes specifically for the new thread that incorporated the data, which was assigned to properties, and the thread entry point.
    vb.net Code:
    1. Private Class Worker
    2.  
    3.     Private _data As Integer
    4.  
    5.     Public WriteOnly Property Data() As Integer
    6.         Set(ByVal value As Integer)
    7.             Me._data = value
    8.         End Set
    9.     End Property
    10.  
    11.     Public Sub DoWork()
    12.         Dim data As Integer = Me._data
    13.  
    14.         'Use data here.
    15.     End Sub
    16.  
    17. End Class
    18.  
    19.  
    20. Private Sub InitiateThread()
    21.     Dim w As New Worker
    22.  
    23.     w.Data = 100
    24.  
    25.     Dim t As New Thread(AddressOf w.DoWork)
    26.  
    27.     t.Start()
    28. End Sub
    With .NET 2.0 came the ParameterizedThreadStart delegate and the ability to pass a single object to the entry method via the Thread.Start method.
    vb.net Code:
    1. Private Sub InitiateThread()
    2.     Dim t As New Thread(AddressOf DoWork)
    3.  
    4.     t.Start(100)
    5. End Sub
    6.  
    7. Private Sub DoWork(ByVal obj As Object)
    8.     Dim data As Integer = CInt(obj)
    9.  
    10.     'Use data here.
    11. End Sub
    Now, with VB 2008, we have a new way, thanks to Lambda Expressions. This is easier and neater than the old ways and overcomes the weak typing required by the ParameterizedThreadStart delegate. With this new approach you can write a function that takes as many arguments as you like of whatever type you like. You then create a ThreadStart delegate using a Lambda Expression that calls this function, e.g.
    vb.net Code:
    1. Private Sub InitiateThread()
    2.     Dim t As New Thread(DirectCast(Function() DoWork(100), ThreadStart))
    3.  
    4.     t.Start()
    5. End Sub
    6.  
    7. Private Function DoWork(ByVal data As Integer) As Object
    8.     'Use data here.
    9.  
    10.     Return Nothing
    11. End Function
    The only real drawback with this approach is that your work method MUST be a function, even though the return value cannot be used anywhere. When VB 2010 arrives that will no longer be the case because Lambda Expressions will be able to be Subs as well as Functions.

    I have to admit that I don't really understand how a cast from a Lambda Expression that's a function to type ThreadStart, which has no return type, is legal but it seems to work so I'm happy to use it.
    Last edited by jmcilhinney; Dec 28th, 2008 at 11:16 PM.
    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

  2. #2

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing Data to a Thread Entry Method

    VB 2010 has added support for action lambdas to the existing value lambdas, i.e. you can now create a lambda expression using the Sub keyword as well as the Function keyword. As such, the issue with the last code snippet in post #1 is removed in VB 2010:
    vb.net Code:
    1. Private Sub InitiateThread()
    2.     Dim t As New Thread(DirectCast(Sub() DoWork(100), ThreadStart))
    3.  
    4.     t.Start()
    5. End Sub
    6.  
    7. Private Sub DoWork(ByVal data As Integer)
    8.     'Use data here.
    9. End Sub
    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

  3. #3
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: Passing Data to a Thread Entry Method

    hello thanks jmcilhinney for this brief,

    in the class approach of this threading, will this method avoid data overwriting (race condition) since the same DoWork will be used by multiple threads
    since you say

    vb Code:
    1. Private Sub InitiateThread()
    2.     Dim w As New Worker
    3.  
    4.     w.Data = 100
    5.  
    6.     Dim t As New Thread(AddressOf w.DoWork)
    7.  
    8.     t.Start()
    9. End Sub
    Programming is all about good logic. Spend more time here


    (Generate pronounceable password) (Generate random number c#) (Filter array with another array)

  4. #4

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing Data to a Thread Entry Method

    Quote Originally Posted by coolcurrent4u View Post
    hello thanks jmcilhinney for this brief,

    in the class approach of this threading, will this method avoid data overwriting (race condition) since the same DoWork will be used by multiple threads
    since you say

    vb Code:
    1. Private Sub InitiateThread()
    2.     Dim w As New Worker
    3.  
    4.     w.Data = 100
    5.  
    6.     Dim t As New Thread(AddressOf w.DoWork)
    7.  
    8.     t.Start()
    9. End Sub
    But it's not the same DoWork method. You're creating a new Worker object each time and each of those objects has its own Data property and DoWork method. It would only be if you used the same Worker object each time or Worker was a module or a class with Shared members that you would experience interference between threads.
    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

  5. #5
    Fanatic Member coolcurrent4u's Avatar
    Join Date
    Apr 2008
    Location
    *****
    Posts
    993

    Re: Passing Data to a Thread Entry Method

    Hello John

    Am getting race condition with this implementation. in the listview, one item is usually listed more than once, which is not suppose to be so. The my code

    I wanted to use the class implementation, but how do i get the clas to return values so i can display it in list view just like thsi one

    vb Code:
    1. Sub Button1Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnStart.Click
    2.         ListItemsToProcess.AddRange(TextBox1.Lines)
    3.         count = 0
    4.         StartProcess()
    5.     End Sub
    6.  
    7.     Private Sub StartProcess()
    8.         Me.btnStart.Enabled = False
    9.         ' start the first five threads
    10.         For i = 0 To intMaxThreadCount - 1
    11.             If intNextItemIndex < ListItemsToProcess.Count Then
    12.                 Threading.Thread.Sleep(100)
    13.                 StartNextItem(i)
    14.             End If
    15.         Next
    16.         ' update running threads
    17.     End Sub
    18.  
    19.     Private Sub StartNextItem(ByVal index As Integer)
    20.         If index < ListItemsToProcess.Count Then
    21.             ' start parsing thread
    22.             Dim t As New Thread(AddressOf DoWork)
    23.             t.Name = "Thread " & index
    24.             t.Start(index)
    25.             intNextItemIndex += 1
    26.         End If
    27.     End Sub
    28.  
    29.     Private Sub DoWork(ByVal data As Object)
    30.         Dim index As Integer = CInt(data)
    31.         Dim sTemp As String = Nothing
    32.         Dim objLock As Object = New Object()
    33.         Dim t As Double = 0
    34.         myWatch = New Stopwatch
    35.         Try
    36.             ' Proces item
    37.             myWatch.Start()
    38.             SyncLock (objLock)
    39.                 sTemp = ProcessData(ListItemsToProcess(index).ToString)
    40.                 'sTemp = CountTo().ToString
    41.             End SyncLock
    42.             myWatch.Stop()
    43.             t = myWatch.ElapsedMilliseconds / 1000
    44.         Catch ex As Exception
    45.             ' catch error
    46.             sTemp = ex.Message
    47.             Debug.Print(sTemp)
    48.         End Try
    49.         Debug.Print(index.ToString)
    50.         'AddItem(index, sTemp)
    51.         AddItem(index, t.ToString)
    52.         StartNextItem(intNextItemIndex)
    53.     End Sub
    54.  
    55.     Public Delegate Sub AddItemDelegate(ByVal index As Integer, ByVal item As String)
    56.  
    57.     Public Sub AddItem(ByVal index As Integer, ByVal item As String)
    58.         Dim objLock As Object = New Object()
    59.         If Me.InvokeRequired Then
    60.             Me.Invoke(New AddItemDelegate(AddressOf AddItem), index, item)
    61.         Else
    62.             Dim lvItem As New ListViewItem
    63.             With lvItem
    64.                 .Text = index.ToString
    65.                 .SubItems.Add(ListItemsToProcess(index).ToString)
    66.                 If item.Length < 51 Then
    67.                     .SubItems.Add(item.ToString)
    68.                 Else
    69.                     .SubItems.Add(item.Length.ToString)
    70.                 End If
    71.  
    72.             End With
    73.             count = Interlocked.Increment(count)
    74.             tspbStatus.Value = CInt((count / ListItemsToProcess.Count) * 100)
    75.             SyncLock (objLock)
    76.                 listView1.Items.Add(lvItem)
    77.             End SyncLock
    78.  
    79.         End If
    80.  
    81.     End Sub
    Last edited by coolcurrent4u; Jun 9th, 2011 at 05:53 AM.
    Programming is all about good logic. Spend more time here


    (Generate pronounceable password) (Generate random number c#) (Filter array with another array)

  6. #6
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,401

    Re: Passing Data to a Thread Entry Method

    Hi john, would it be rude to ask a quick question on thread termination here? I dont really feel it needs it's own thread.

  7. #7

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Passing Data to a Thread Entry Method

    Quote Originally Posted by ident View Post
    Hi john, would it be rude to ask a quick question on thread termination here? I dont really feel it needs it's own thread.
    The thread title says "Passing Data to a Thread Entry Method". Is your question about that? It would appear not, so it doesn;t belong in this thread.
    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

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