Here is the code:
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
progressbar1.visible = True
Dim psInfo As New System.Diagnostics.ProcessStartInfo("c:\blabla.exe)
psInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
Dim myProcess As Process = System.Diagnostics.Process.Start(psInfo)
myProcess.WaitForExit()
MsgBox(" Completed Successfully", MsgBoxStyle.Information,
"Completed")
End Sub
Thanks and regards...
Anyway i tried with %40-50 cpu-costing external application with
similar negative result. While external process is running, the main
VB form is corrupted and distorted visually, as appearence and you
cannot click or modify main form during external process runs.
No, "myProcess.WaitForExit()" is the reason. If it waits it, when is it to
display the progressbar? Use "progressbar1.refresh" directly after showing
it.
> Anyway i tried with %40-50 cpu-costing external application with
> similar negative result. While external process is running, the main
> VB form is corrupted and distorted visually, as appearence and you
> cannot click or modify main form during external process runs.
The short solution in this case is: Handle the process' Exited event instead
of waiting for the exit.
Want some background information?....
The OS is message based. It sends messages to the applications, for example
to inform about user input like mouse clicks and keyboard input. The
application must process the messages. We can react to them by handling
Click (and other) events. The OS puts the messages into a queue because the
application might still be busy handling the previous message. It is called
the "message queue". The application processes the messages in a loop, one
after the other. It is called the "message loop".
The OS maintains a list of visually "invalidated" areas on the screen. If
you show a progress bar, the OS adds the control's rectangle to that list
because that part of the screen must be updated (I keep it simple here). In
addition, the OS sends a message (called WM_PAINT; WM=windows message) to
the application, more precisely to the control, in order to tell it that it
must paint itself.
If you specify a Form as the startup object in the project's properties, VB
internally creates a call to "Application.Run". Guess what "Run" does?
Right, it contains the message loop that processes the arrived messages. It
keeps the application responsive by processing the click notifications and
paint requests.
In your case, Sub Button1_Click is the reaction to a message. In it, you
display the progress bar. In short, this makes the OS send a message to the
progress bar in order to paint itself. As explained above, the message is
put in the queue, but as long as the Click message for the Button hasn't
been processed completely, the Paint message for the progress bar can not be
processed. That's how it is with sub procedures: The main procedure (the
message loop) won't continue before the sub procedure (Sub Button_Click) has
exited. Therefore, the progress bar isn't painted before the Click event
procedure exited.
Calling progressbar1.refresh /immediatelly/ paints the progress bar, but in
order to keep the whole Form responsive, you must return from Sub
Button_Click as soon as possible. Now we have a problem: On the one hand, we
want to wait and on the hand we want to keep on processing messages. There
is only one way to do two things at one time: Create another thread.
Multiple threads are meant to be executed synchronously. So, the solution is
to create another thread that does what has to be done simultaneously.
Multi threading explained:
http://msdn2.microsoft.com/en-us/library/3e8s7xdd.aspx
http://msdn2.microsoft.com/en-us/library/eed6swsx(VS.80).aspx
Armin
Nice explanation and even without the so by me damned words "message pump".
:-)
Cor
Thanks :)
> and even without the so by me damned words "message
> pump".
I'll put it in my synonym list. ;)
Armin
Mr. Zingler,
Thank you for your detailed answer.
Right
> So is
> the unique way to set multi-threading to use waitforexit() effect
> and main form interaction at the same same time with external
> process?
Sorry, I don't understand. If you want to wait for exit, you either can
handle the process' Exited event or you can call waitforexit in another
thread. For this purpose I'd prefer handling the Exit event.
Armin
Thanks Armin, so could you give a simple example about handle exit
event? Sorry for being newbie and glad to receive help from experts.
Thanks.
Dim p As Process
'...
'start process
'...
AddHandler p.Exited, AddressOf OnProcessExited
Private Sub OnProcessExited( _
ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox("exited")
End Sub
Armin
Thanks but sorry, "OnProcessExited" cannot be found via intellisense.
I'm using vb.net 2005 express.
There are a lot of intellisense listed OnXXXXX statements but there's
no "OnProcessExited" beleive. :(
Look at the code Armin posted. OnProcessExited is defined in that
code.