Solved

Help with threading/progress bars...

Posted on 2007-11-19
8
330 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
ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 

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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
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…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

777 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