Help with threading...

G

Guest

Using VS 2003, .NET:
I developed a windows application that performs several actions based on an
input file. The application displays a progress bar as each action executes.
Based on new requirements, this application needs to be able to shell off
other processes and wait while in the mean time displaying a progress bar of
the process's. I am using the System.Disgnostics.Process class to "start"
and "waitForExit" of these processes... I thought the best way to show status
was to kick off a separate thread that increments a progress bar on my GUI
while the processes's hasExited value is false... unfortunately this is not
working well for me. As I step through the code, everything looks good until
line 11 below executes... after executing this line nothing happens and the
application just hangs. Being a novice to threads, I wasn't sure if my
application of thread was appropriate in this instance (regardless I wanted
to try and make it work as a learning exercise). So, Is my application of a
separate thread appropriate? Should it be implemented differently, etc? Any
idea why the application just hangs after line 11?

Thanks for your attention to this, Charles:


1 Public Class frmMain
2 '....snip...
3 Private oProcess As System.Diagnostics.Process
4 '....snip...
5 Friend WithEvents pgAction As System.Windows.Forms.ProgressBar
6 '....snip...
7 Public Sub New()
8 MyBase.New()
9 'This call is required by the Windows Form Designer.
10 InitializeComponent()
11 'Add any initialization after the InitializeComponent() call
13 Me.MyMain()
14 End Sub
15 '....snip...
16 Private Sub IncrementActionProgress()
17 While Not oProcess.HasExited 'HACK start with a the progress bar
moving up 2 steps / second
18 If Me.pgAction.Value = 100 Then Me.pgAction.Value = 0 'Keep
going till thread is aborted...
19 Me.pgAction.Increment(1) 'declaration not shown...
20 System.Threading.Thread.CurrentThread.Sleep(500)
21 End While
22 End Sub
23 '....snip...
24 Private Sub MyMain
25 oProcess = New System.Diagnostics.Process
26 Try
27 oProcess.StartInfo.FileName = Process
28 oProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
29 oProcess.Start()
30 Dim t As System.Threading.Thread
31 t = New System.Threading.Thread(AddressOf
Me.IncrementActionProgress)
32 t.Start()
33 oProcess.WaitForExit()
34 t.Abort()
35 Me.pgAction.Value = Me.pgAction.Maximum 'Ensure that
progress bar goes to max...
36 Catch ex As Exception
37 Msgbox "Error: " & Err.Message 'TODO handle error
gracefully...
38 End Try
39 End Sub
 
C

Cor Ligthert [MVP]

Hi,

If you want to use a progressbar, than you need to know

The Start
The in advance measured time or totalsteps that will be involved
The steps.

You know only the Start so your program makes in my opinion not much sense.

Cor
 
K

Kevin Spencer

Hi Charles,

The problem is that a Windows Form is STA Threaded. Your threads are
multi-threaded. They cannot operate directly on the Form thread. Instead,
methods on the main thread have to be marshalled to it. There is a good
series of articles in the MSDN library about this. Read all 3 of them
carefully. It's not all that easy to grasp!

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms08162002.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms08162002.asp

--
HTH,

Kevin Spencer
Microsoft MVP
Professional Numbskull

Hard work is a medication for which
there is no placebo.
 
G

Guest

Actually, I do know how many steps (totalsteps) and the expected duration of
the processes to be shelled... the code below was me just trying to see if I
could get it to work...
 
G

Guest

Ok, I'll take a read... thanks for the reference.
If I have questions about those articles, I'll post them here.
 
G

Guest

I read the above articles (second link is duplicated) and implemented some
changes in my code...(no more threading but async calls?) but my GUI still
does not get updated - actually, after the new process is started, my GUI
doesn't get painted again until after that process has completed - so it
appears that this is not working for me... is this because I'm doing all my
work in one class (frmMain)? Anyway, here's the code that I've got now. What
am I doing wrong here?

Public Class frmMain
'....snip...
Private oProcess As System.Diagnostics.Process
'....snip...
Friend WithEvents pgAction As System.Windows.Forms.ProgressBar
'....snip...
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.MyMain() 'Process actions...
End Sub
'....snip...
Private Sub IncrementActionProgress()
If Me.pgAction.InvokeRequired Then
'Show progress asynchronously
Dim iapd As IncrementActionProgressDelegate = _
New IncrementActionProgressDelegate(AddressOf
IncrementActionProgress)
Me.BeginInvoke(iapd)
Else
If Me.pgAction.Value = 100 Then Me.pgAction.Value = 0
Me.pgAction.Value += 1
Me.Refresh()
System.Threading.Thread.Sleep(500)
End If
End Sub

Delegate Sub IncrementActionProgressDelegate()

Private Sub MyMain()
oProcess = New System.Diagnostics.Process
Try
oProcess.StartInfo.FileName = Process
Me.pgAction.Value = 0
oProcess.Start()
While Not oProcess.HasExited
Me.IncrementActionProgress()
End While
oProcess.WaitForExit() 'Yes, this is redundant...
Me.pgAction.Value = Me.pgAction.Maximum
Catch ex As Exception
'TODO Handle error gracefully
End Try
End Sub
'....snip...
End Class
 
A

anthony.shaw

I do most of my programming in C#, but I'm sure there is a call in
vb.net that coorisponds to the this.Update() or even this.Refresh()
function at form level.

I use this to update my forms when I need it to post info back to the
form before it finishes executing and repaints the form.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top