Solved

Help with threading/progress bars...

Posted on 2007-11-19
8
326 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
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…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

762 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

18 Experts available now in Live!

Get 1:1 Help Now