Solved

Help with threading/progress bars...

Posted on 2007-11-19
8
328 Views
Last Modified: 2013-11-27
Either I'm not using the threads correctly or I'm misunderstanding what they are supposed to do. What I am trying to do is run a process that takes about 30 seconds to run with a progress bar that either shows the acual process or just shows that it is not frozen. In order to accomplish this I believe I need to have the process run on a different thread, but it still freezes up the form until it is complete.
I've tried both of the following methods for starting a new thread:
  Private Sub Go_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Go.Click
        Dim mythread As New ThreadStart(AddressOf tmupdate)
        mythread.Invoke()
 End Sub
And
 Private Sub Go_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Go.Click
        Dim mythread As New Thread(AddressOf tmupdate)
        mythread.Start()
 End Sub

Suggestions?
0
Comment
Question by:jcamping
  • 2
  • 2
  • 2
  • +2
8 Comments
 
LVL 18

Expert Comment

by:jcoehoorn
ID: 20313793
Look at the BackgroundWorker component.  It handles most of the threading issues for you.
0
 
LVL 10

Expert Comment

by:MrClyfar
ID: 20313801
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 20313996
"I am trying to do is run a process that takes about 30 seconds to run with a progress bar that either shows the acual process"

So you are updating a progress bar from the thread?  GUI controls only run in the MAIN UI thread....so if you run a tight loop in a seperate thread BUT update a progress bar with each iteration of the loop...the main UI thread STILL has to basically to execute code in "parallel" with the other thread to update itself.

Threads don't magically give you "extra" processing time.  Consider updating the progress bar less frequently...like every 100 iterations for instance (this really depends on your actual situation!).  Another option would be to use a standard Timer from the ToolBox in the main UI and update the progresss bar every 1/2 second using global values that are updated from the thread.  This is usually less taxing than updating the progress bar directly from the thread since you don't need to use delegates/invoke to marshal the calls across the threads.

The BackgroundWorker control mentioned above makes this type of coding easier BUT you still need to "throttle" back how often you update the progress bar.  =)

0
 

Author Comment

by:jcamping
ID: 20314744
When using a backgroundWorker I get the following error:
"Cross-thread operation not valid: Control 'PCNames' accessed from a thread other than the thread it was created on."
Below is a simplified version of the code:

Further suggestions?
 Private Sub Go_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Go.Click

        BackgroundWorker1.RunWorkerAsync()

    End Sub
 

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Dim worker As System.ComponentModel.BackgroundWorker = _

       CType(sender, System.ComponentModel.BackgroundWorker)

Dim i As Integer

        For i = 1 To PCNames.SelectedItems.Count      '<------Where it points to in the error

            strcomputer = PCNames.SelectedItems.Item(i - 1) ' & vbCr & vbLf

            Dim stopsvc1 As New ThreadStart(AddressOf stopservice1)

            Dim startsvc1 As New ThreadStart(AddressOf startservice1)

           

            Dim environmentKey As Microsoft.Win32.RegistryKey

            Try

                environmentKey = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey( _

                Microsoft.Win32.RegistryHive.LocalMachine, strcomputer).OpenSubKey _

                ("SOFTWARE\TrendMicro\PC-cillinNTCorp\CurrentVersion\", True)
 

                environmentKey.SetValue("server", "us1300-a01.corp.ads", Microsoft.Win32.RegistryValueKind.String)
 

                If environmentKey.GetValue("server") = "us1300-a01.corp.ads" Then

                    My.Computer.FileSystem.WriteAllText("c:\temp\tmlog.txt", "Server updated to us1300-a01.corp.ads" & vbNewLine, True)

                Else

                    My.Computer.FileSystem.WriteAllText("c:\temp\tmlog.txt", "Server failed to update to us1300-a01.corp.ads" & vbNewLine, True)

                End If
 

            Catch ex As Exception

                My.Computer.FileSystem.WriteAllText("c:\temp\tmlog.txt", ex.ToString & vbNewLine, True)

            End Try
 

            My.Computer.FileSystem.WriteAllText("c:\temp\tmlog.txt", vbNewLine, True)

            Me.ServiceController1.ServiceName = "tmlisten"

            startsvc1.Invoke()

            prog1 = prog1 + 1

            Me.ServiceController1.ServiceName = "ntrtscan"

            startsvc1.Invoke()

            prog1 = prog1 + 1

            My.Computer.FileSystem.WriteAllText("c:\temp\tmlog.txt", vbNewLine, True)

      

End Sub

Open in new window

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 125 total points
ID: 20314993
Build yourself a List of the Items you will be working with and place them where the BackgroundWorker can access them:

    Private computers As List(Of String)

    Private Sub Go_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Go.Click
        computers = New List(Of String)
        For i As Integer = 1 To PCNames.SelectedItems.Count
            computers.Add(PCNames.SelectedItems.Item(i - 1))
        Next
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        ...
            For Each strComputer As String in computers
                ' do something with "strComputer"
            Next
        ...
    End Sub
0
 
LVL 2

Expert Comment

by:SZachmann
ID: 20316760
Do you want to show the progress bar from the main form or on a pop up form?  I typically show the progress on a pop up form and do the work on the main form.  Here is a quick step by step, hope it helps.

1. Add a module add put a variable for progress and a complete variable
2. Create a new form called progreesBar
3. Setup a timer to update your progress bar with the value from the progress variable in the module and check to see if the complete variable has changed if so close the form.
4. Create a sub that opens the progresbar form as a modal form
     Private Sub openProgressThread()
          Dim progressWindow As New progressBar
          progressWindow.ShowDialog()
     End Sub
5. Before you start your loop, Create a thread for the openProgress sub and start it
    progressThread = New System.Threading.Thread(AddressOf openProgressThread)
    progressThread.Start()
6. In your loop update the progress variable as needed
7. After your loop kill change the complete variable in the module to end the progress thread
0
 

Author Comment

by:jcamping
ID: 20320244
SZachmann,
You may have overlooked my expertise level, but I really don't know what I'm doing with this. The amount that I have put together is all from snips of code. You have supplied some snippets, but I'm not sure what you're suggesting on steps 1, 3, 6, or 7. Could you please provide some code?
0
 
LVL 2

Expert Comment

by:SZachmann
ID: 20320615
I can post code later tomorrow, but here is a great article by devX.  http://www.devx.com/getHelpOn/10MinuteSolution/20365/0/page/3
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Library to convert HTML to PDF. 8 57
help with issues with ReportViewer in VS2015 5 38
Visual Studio 2013 Shortcut (VB) 4 34
Vb.net dynamic formulas in runtime 11 62
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

920 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now