Click here to Skip to main content
15,919,613 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,
I'm having difficulty in working with MultiThreading.
I want to add to my project a ProgressBar to show the working flow.
I'm getting combinations from many Strings, the number of combination can be really big, so it takes few seconds or minutes.
I added a ProgressBar and assigned its properties,
but I found out that it won't show the changes on the interface, so I searched the net and found that I have to use multi threads.
below you will find my code, it doesn't work with me, right now the method I'm calling "InitializtPB" is not doing anything, and when I made few changes by using "Delegate Function" it gave me what appears to be a common bug "cross thread operation not valid". Any help would be appreciated, since I'm close to my deadline, thanks in advance...

The button that starts all the process:
VB
Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click
        Dim lThread As Thread

        lThread = New Thread(AddressOf Me.Iterate)
        lThread.IsBackground = True
        lThread.Start()
    End Sub


my Subroutine "Iterate":
VB
Private Sub TheIteration()
        Dim dbrec As dbRecordSet
        Dim lItemsList As New Dictionary(Of String, dbRecordSet)
        Dim lItem As String
        Dim i As Integer
        Dim k As Integer
        Dim l As Integer
        Dim lRecordID As String
        Dim lLength As String
        Dim lQty As String
        Dim lPos As String
        Dim TT() As String
        Dim lCalculatedItemsList As New Dictionary(Of String, String())
        Dim lSeperatedCalculatedItemsList As New Dictionary(Of String, String())
        Dim lNbOfTubes As Long
        Dim lItemQty As Long
        Dim lSeperatedItemsList() As String
        Dim lPossibleCuteDistributions As Dictionary(Of Integer, String())

        'I removed the code where I fill my variables (lItemsList)
        CallInitializePBInThread(0, 100, 10, 0, "My text")

        For Each lItem In lItemsList.Keys
            i = 0
            k = 0
            dbrec = lItemsList(lItem)
            lRecordID = ""
            lQty = "0"
            lLength = "0"
            lPos = ""
            ReDim TT(0)
            ReDim lSeperatedItemsList(0)

            Do While Not dbrec.EOF
                ProjectsCls.GetItemRecordProperties(dbrec.RS(k), lRecordID, lQty, lPos, lLength)
                ReDim Preserve TT(i)
                TT(i) = lRecordID & ":" & lPos & ":" & lLength & ":" & lQty

                For l = 1 To CInt(lQty)
                    lSeperatedItemsList(UBound(lSeperatedItemsList)) = lRecordID & ":" & lLength
                    ReDim Preserve lSeperatedItemsList(UBound(lSeperatedItemsList) + 1)
                Next

                i = i + 1
                k = k + 1
                lItemsList(lItem).MoveNext()
            Loop

            ReDim Preserve lSeperatedItemsList(UBound(lSeperatedItemsList) - 1)
            lSeperatedCalculatedItemsList.Add(lItem, lSeperatedItemsList)
            lCalculatedItemsList.Add(lItem, TT)

            IncrementPB()
        Next
    End Sub


The Sub that initializes my ProgressBar:
VB
Private Sub InitializePB(ByVal pMin As Integer, ByVal pMax As Integer, ByVal pStep As Integer, ByVal pValue As Integer, ByVal pText As String)
    ProgressBar1.Minimum = pMin
    ProgressBar1.Maximum = pMax
    ProgressBar1.Value = pValue
    ProgressBar1.Step = pStep
    lblProgress.Text = pText
End Sub


Delegate function for InitializePB:
VB
Private Delegate Sub DelInitializePB(ByVal pMin As Integer, ByVal pMax As Integer, ByVal pStep As Integer, ByVal pValue As Integer, ByVal pText As String)


The Sub I call inside the created thread to access the ProgressBar:
VB
Private Sub CallInitializePBInThread(ByVal pMin As Integer, ByVal pMax As Integer, ByVal pStep As Integer, ByVal pValue As Integer, ByVal pText As String)
    Dim lDel As DelInitializePB

    If Me.InvokeRequired Then
        lDel = New DelInitializePB(AddressOf InitializePB)
        lDel.Invoke(pMin, pMax, pStep, pValue, pText)
    End If
End Sub


The Sub that increments the ProgressBar Value:
VB
Private Sub IncrementPB()
    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf IncrementPB))
    Else
        ProgressBar1.Value += 1
        ProgressBar1.PerformStep()
        ProgressBar1.PerformClick()
    End If
End Sub


When I call "InitializePB", the exception occurs on the first code line "Progress.Visible = True" :S
Posted
Updated 12-Aug-11 7:22am
v3

This is not a bug in the framework, you're just not using these things properly. You seem to be calling Invoke, so I'm not sure why you'd get an exception, unless you have code that sets the progress bar ? I don't recognise what your code is doing when it calls invoke tho, it should invoke the progress bar to increment, etc.

The easy solution is to use the BackgroundWorker class, which can then be told to generate an event on the main UI thread to set the progress, or to report success.
 
Share this answer
 
I found the solution for my problem :D, here it is:
VB
Private Sub CallInitializePBInThread(ByVal pMin As Integer, ByVal pMax As Integer, ByVal pStep As Integer, ByVal pValue As Integer, ByVal pText As String)

        If Me.ProgressBar1.InvokeRequired Then
            Me.ProgressBar1.Invoke(New DelInitializePB(AddressOf CallInitializePBInThread), New Object() {pMin, pMax, pStep, pValue, pText})
        Else
            Me.InitializePB(pMin, pMax, pStep, pValue, pText)
        End If
End Sub

I hope this will help someone ;)
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900