Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Help with threading/progress bars...

Posted on 2007-11-19
8
Medium Priority
?
341 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:Joel Coehoorn
ID: 20313793
Look at the BackgroundWorker component.  It handles most of the threading issues for you.
0
 
LVL 10

Expert Comment

by:Jason Evans
ID: 20313801
0
 
LVL 86

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
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 

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
 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 375 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

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

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

Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
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…
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…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…

876 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