Solved

Visual Basic .NET Multithreading

Posted on 2010-11-20
10
429 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1
10 Comments
 
LVL 86

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 36

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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 86

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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
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…

740 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