Solved

Visual Basic .NET Multithreading

Posted on 2010-11-20
10
424 Views
Last Modified: 2013-11-26
Hello.

I have a problem with threads. In my program count of threads is user defined.
Threads working only once without completing the computation.  I don't know how to fix it..
Code + Screenshot attached.

Thanks.


Imports System.Threading

Public Class MultiThread
    Private Delegate Sub addToListBox_d(ByVal result As String)
    Private num As New Integer
    Private step1 As Integer = 1

    Private Sub addToListBox(ByVal result As String)
        If Me.InvokeRequired() Then
            Me.Invoke(New addToListBox_d(AddressOf addToListBox), New Object() {result})
        Else
            ListBox.Items.Add(result)
        End If
    End Sub

    Private Sub DoWork(ByVal state As Object)
        Dim txtToAdd As String
        Dim result As Integer = 0
        Dim counter As Integer = Val(state)
        Dim stop1 As Integer = Val(state) + step1
        Do While (counter < stop1)
            result += counter
            counter += 1
        Loop
        txtToAdd = state & " - " & result
        addToListBox(txtToAdd)
    End Sub

    Private Sub StartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartButton.Click
        Dim counter As Integer = 1
        Do While (counter < Val(Threads.Text) + 1)
            Dim t As Thread = New Thread(AddressOf DoWork)
            t.IsBackground = True
            t.Start(counter)
            t.Join(counter)
            counter += step1
        Loop
    End Sub
End Class

Open in new window

screen.jpg
0
Comment
Question by:StolenMan
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34179876
What were you expecting to happen here?...that's some messy code to decipher...

Also, you have:

            t.Join(counter)

Which will only block for a mere couple of milliseconds and then move on.

Again, can you explain what the code is supposed to do?
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34179937
What output are you expecting?
0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 34180969
Join the threads at the end not at creation time
Private Sub StartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartButton.Click
        Dim counter As Integer = 1
        Dim result As New List(Of Thread)
        Do While (counter < Val(Threads.Text) + 1)
            Dim t As Thread = New Thread(AddressOf DoWork)
            t.IsBackground = True
            t.Start(counter)
            result.Add(t)
            counter += step1
        Loop
        For Each Item As Thread In result
            Item.Join()
        Next
    End Sub

Open in new window

0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:StolenMan
ID: 34181949
Idle_Mind, program does not continues computing. Thread creation not repeating.
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34182939
Can you explain what the code is supposed to do and what should be the expected results?
0
 

Author Comment

by:StolenMan
ID: 34183101
I need any program with user defined count of threads (with GUI)... Very compact sample.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 34183518
How about something like this?

The form has a NumericUpDown, Button, and ListBox:
Imports System.ComponentModel
Public Class Form1

    Private R As New Random
    Private BackgroundWorkers As New List(Of BackgroundWorker)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Static Counter As Integer

        ListBox1.Items.Clear()
        Button1.Enabled = False
        For i As Integer = 1 To NumericUpDown1.Value
            Dim bgw As New BackgroundWorker
            bgw.WorkerReportsProgress = True
            AddHandler bgw.DoWork, AddressOf bgw_DoWork
            AddHandler bgw.ProgressChanged, AddressOf bgw_ProgressChanged
            AddHandler bgw.RunWorkerCompleted, AddressOf bgw_RunWorkerCompleted
            BackgroundWorkers.Add(bgw)
            Counter = Counter + 1
            bgw.RunWorkerAsync(Counter)
        Next
    End Sub

    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
        Dim ThreadID As Integer = e.Argument
        Dim bgw As BackgroundWorker = CType(sender, BackgroundWorker)
        For i As Integer = 1 To 10
            System.Threading.Thread.Sleep(R.Next(1000, 5001))
            bgw.ReportProgress(0, "ThreadID: " & ThreadID & " --> Progress: " & i)
        Next
    End Sub

    Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
        ListBox1.Items.Add(e.UserState.ToString)
    End Sub

    Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
        Dim bgw As BackgroundWorker = CType(sender, BackgroundWorker)
        BackgroundWorkers.Remove(bgw)
        If BackgroundWorkers.Count = 0 Then
            MessageBox.Show("Done!")
            Button1.Enabled = True
        End If
    End Sub

End Class

Open in new window

0
 
LVL 63

Accepted Solution

by:
Fernando Soto earned 500 total points
ID: 34183573
Hi StolenMan;

I have uploaded a sample project that you can download at this link.
https://filedb.experts-exchange.com/incoming/ee-stuff/8030-WindowsApplication3.zip 

The code looks like this:

Imports System.Threading

Public Class Form1

    ' A delegate to display info from a non UI thread
    Private Delegate Sub addToListBox_d(ByVal result As String)
    ' A count variable, one for each thread
    Private threadCounters As New List(Of Integer)()
    ' A count of the number of times to loop in the DoWork thread
    Private maxCount As Integer
    ' Used as a program lock to block other threads from using the
    ' code until the current thread is finish using it.
    Private threadLock As New Object

    ' To display results in the list box from another thread
    Private Sub addToListBox(ByVal result As String)
        If Me.InvokeRequired() Then
            Me.Invoke(New addToListBox_d(AddressOf addToListBox), New Object() {result})
        Else
            ListBox1.Items.Add(result)
        End If
    End Sub

    ' The thred code
    Private Sub DoWork(ByVal state As Object)
        ' Lock the code from beging used by other threads
        Monitor.Enter(threadLock)
        Try
            ' I assigned the thread number in the button click event to the Name
            ' property of the thread to identify the current executing thread which
            ' used to access the threadCounters List
            Dim threadIndex As Integer = Integer.Parse(Thread.CurrentThread.Name)
            Dim count As Integer = threadCounters(threadIndex)
            ' maxCount was identifed in the UI in the text box txtMaxCount
            For loopCount As Integer = 0 To maxCount - 1
                ' Update the UI with the thread name and loop index count
                addToListBox(Thread.CurrentThread.Name + " : " + loopCount.ToString())
            Next
            addToListBox("==========")
        Finally
            ' Before leaving the code release it for the next thread to use
            Monitor.Exit(threadLock)
        End Try
    End Sub

    Private Sub StartButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartButton.Click

        Dim counter As Integer = 0
        ' The comboBox cboNoOfThreads has the number of threads to create
        Dim threadCount As Integer = Integer.Parse(cboNoOfThreads.Text)

        If Integer.TryParse(txtMaxCount.Text, maxCount) Then
            Do While (counter < threadCount)
                Dim t As Thread = New Thread(AddressOf DoWork)
                t.IsBackground = True
                ' Name the thread so we can identify it in the thread code.
                t.Name = counter.ToString()
                ' Initialize the counter for this thread
                threadCounters.Add(0)
                t.Start(counter)
                counter += 1
            Loop
        End If

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'initialize to combo box to the first value in its list
        cboNoOfThreads.SelectedIndex = 0
    End Sub

End Class

Open in new window

0
 

Author Closing Comment

by:StolenMan
ID: 34183920
Thank you very much!
0
 
LVL 63

Expert Comment

by:Fernando Soto
ID: 34184231
Not a problem; glad to help.  ;=)
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question