Form controls wont update until whole sub has run.

djheath

New member
Joined
Sep 3, 2008
Messages
3
Programming Experience
Beginner
Firstly, apologies if I don't get the terms correct, or my sample code is a bit "hap hazzard". I am new to programming so don't really know the best practices yet.

My problem is this:

I have a windows form. When a button is pressed, it runs a process to run an external batch file. When the batch file finishes running it creates a file in a predefined directory. I want the form to, update a label with some text, show a progress bar which scrolls continuously in marquee mode, which will show the batch file is running. Then when the file is created, it will stop and show a msgbox.
I am doing this all with the code below:

VB.NET:
Private Sub AggregateBut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AggregateBut.Click
'disable the button just pressed
        AggregateBut.Enabled = False

'update the help text label with useful information
 HelpText.Text = "Daily script file is now running.  This takes approximately 45 minutes to complete." _
        & vbCrLf & "A Success message will be displayed once the operation has finished."

'show the progress bar
        ProgressBar.Visible = True
        
'run the script using the runScript program
        runScript(scriptName)
       
'check to see if script has finished running by looking for the output file
        While My.Computer.FileSystem.FileExists("C:\personal\file") = False
        'sleep for 10 seconds before checking again
              System.Threading.Thread.Sleep(1000)  
        End While

'delete the output, but check its there first incase its been deleted first
        If My.Computer.FileSystem.FileExists("C:\personal\file") Then
            My.Computer.FileSystem.DeleteFile("C:\personal\file")
        End If

'hide the progress bar
        ProgressBar.Visible = False

'show a successful message box to say its complete
        MsgBox("File Aggregation Complete", MsgBoxStyle.OkOnly, "Aggregation complete")

'update the text label with more useful info.
        HelpText.Text = "Aggregation complete.  Please check the database status for any session errors."

    End Sub

So, when the button is pressed, the script file is run by using another private sub I have created called runScript(scriptname).
Then I update some text on the form to give some info on the script file.
Then I make the progress bar visible which is in marquee style so it just scrolls.
Then I check for the file that is created by the script file and if its not found I wait ten seconds, then check again.
If the file is found, I check to make sure its there then delete it.
I then make the progress bar hidden.
Show a message saying job complete and then update the text field again to give some more info on whats happened.

The problem is, none of the stuff that occurs before the while loop happens, I assume because the while loop is running and the form wont refresh its look until the whole sub is finished running. What is the best way to make sure the first few tasks (update text label, show the progress bar) happen before the while true loop starts running?
Thanks,

Sorry for length.
 
It's terrible.

You spend a day trying to work the problem out, then 10 minutes after typing all the above you figure it out.

I just added a me.refresh() command during the while statement!

Jobs a gooden!
 
Just a suggestion but I would recommend a file system watcher rather than calling thread.sleep every second.

VB.NET:
Public WithEvents fsw As New System.IO.FileSystemWatcher()

VB.NET:
	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	Handles Button1.Click

		fsw.Path = "C:\Temp\"
		fsw.Filter = "File"
		fsw.IncludeSubdirectories = False
		fsw.NotifyFilter = IO.NotifyFilters.FileName
		fsw.EnableRaisingEvents = True

	End Sub

VB.NET:
	Private Sub fsw_Created(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) _
	Handles fsw.Created

		IO.File.Delete("C:\Temp\File")
		MessageBox.Show("File Aggregation Complete", "Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Information)

	End Sub
 
Sleeping the UI thread is a bad idea, whether you do Application.DoEvents or not, there are better ways. The FileSystemWatcher component MattP mentioned can be used here (just add one to form and configure it in Designer :)), you have the Timer component if you need reoccuring events, and there are lots of easy multithreading tools in .Net it you want to. Since you started this Process this class also has an option or two to wait for exit.
 
Excellent. Thanks for the help.

Its things like this that I have no idea about. I feel a lot of my coding at the minute is a bit like "re-inventing the wheel" when there is already code available which can do the job in hand.

Thanks again for your help I will have a look at the file watcher.
 
Back
Top