program hangs while batch file is running

Posted on 2006-05-24
Last Modified: 2010-07-27
  When one of the buttons in my program is clicked, it creates a batch file & 2 SQL scripts. It then runs the batch file which runs the 2 SQL scripts which output 2 text files. The text files are then parsed for the data required.
The problem is that when the batch file is running (about 20 seconds) the program & progress form freeze.The skin comes off the form also. Once the batch file finishes the form refresh's itself & the program is fine.
I thought the batch file would run independently of the program & the program would just check to see if it had finished once a second.
Does anyone know how I can get around this so that the forms don't freeze.

      ''' RUN MULTI.BAT
        Dim s As New System.Diagnostics.Process
        s.StartInfo.FileName = Application.StartupPath & "\temp\" & LOT & "MULTI.bat"
        s.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
        i = 0
        Do Until i = 30
            If s.HasExited = False Then
                PROGRESS.ProgressBar1.Value = PROG

                PROG = 32
                PROGRESS.ProgressBar1.Value = PROG
                Exit Do
            End If
            i = i + 1
            PROG = PROG + 1
Thanks for the help,
Question by:e_murf1
    LVL 12

    Expert Comment

    Use threads

    System.Threading.Thread class
    LVL 12

    Expert Comment

    LVL 85

    Accepted Solution

    If you want to hold in a loop that won't lock up the GUI then:

                While Not s.HasExited

    Otherwise here is a threaded implementation that encapsulates the thread in a class:

    Public Class Form1
        Inherits System.Windows.Forms.Form

    #Region " Windows Form Designer generated code "

        Public Sub New()

            'This call is required by the Windows Form Designer.

            'Add any initialization after the InitializeComponent() call

        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                End If
            End If
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents Button1 As System.Windows.Forms.Button
        Friend WithEvents Label1 As System.Windows.Forms.Label
        Friend WithEvents Label2 As System.Windows.Forms.Label
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.Button1 = New System.Windows.Forms.Button
            Me.Label1 = New System.Windows.Forms.Label
            Me.Label2 = New System.Windows.Forms.Label
            Me.Button1.Location = New System.Drawing.Point(40, 40)
            Me.Button1.Name = "Button1"
            Me.Button1.Size = New System.Drawing.Size(104, 24)
            Me.Button1.TabIndex = 0
            Me.Button1.Text = "Button1"
            Me.Label1.Location = New System.Drawing.Point(8, 120)
            Me.Label1.Name = "Label1"
            Me.Label1.Size = New System.Drawing.Size(272, 24)
            Me.Label1.TabIndex = 1
            Me.Label1.Text = "Label1"
            Me.Label2.Location = New System.Drawing.Point(8, 152)
            Me.Label2.Name = "Label2"
            Me.Label2.Size = New System.Drawing.Size(272, 24)
            Me.Label2.TabIndex = 2
            Me.Label2.Text = "Label2"
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(292, 266)
            Me.Name = "Form2"
            Me.Text = "Form1"

        End Sub

    #End Region

        Public Delegate Sub StatusUpdate(ByVal sender As MyProcess, ByVal info As MyProcess.ProcessInfo)

        Private myThreads As New ArrayList

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim mp As New MyProcess("calc")
            AddHandler mp.ProcessUpdate, AddressOf Me.ProcessUpdate
        End Sub

        Private Sub ProcessUpdate(ByVal sender As MyProcess, ByVal info As MyProcess.ProcessInfo)
            ' If necessary, prevent cross-thread UI update violations via Delegates
            If Me.InvokeRequired Then
                Dim su As New StatusUpdate(AddressOf Me.UpdateGUI)
                Me.Invoke(su, New Object() {sender, info})
                UpdateGUI(sender, info)
            End If
        End Sub

        Private Sub UpdateGUI(ByVal sender As MyProcess, ByVal info As MyProcess.ProcessInfo)
            ' do something with the data in here...
            ' (it is safe to update the GUI since a Delegate was used if necessary)

            ' some possibilities...
            Select Case info.Status
                Case MyProcess.ProcessStatus.Complete
                    Select Case info.ExeName
                        Case "calc"
                            Label1.Text = info.ExeName
                            Label2.Text = info.Message

                        Case "c:\prog1.exe"
                            ' take next step...

                    End Select

                Case MyProcess.ProcessStatus.Aborted
                    ' do something else in here..

                Case MyProcess.ProcessStatus.Failed
                    ' or something else in here...

            End Select
        End Sub

        Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
            Dim mp As MyProcess
            For Each mp In myThreads
        End Sub

        Public Class MyProcess

            Public Enum ProcessStatus
            End Enum

            Public Structure ProcessInfo
                Public ExeName As String
                Public Status As MyProcess.ProcessStatus
                Public Message As String

                Public Sub New(ByVal ExeName As String, ByVal Status As ProcessStatus, ByVal Message As String)
                    Me.ExeName = ExeName
                    Me.Status = Status
                    Me.Message = Message
                End Sub
            End Structure

            Public Event ProcessUpdate(ByVal sender As MyProcess, ByVal info As MyProcess.ProcessInfo)

            Private Exe As String
            Private t As System.Threading.Thread
            Private p As Process
            Private abort As Boolean = False

            Public ReadOnly Property ExeName() As String
                    Return Exe
                End Get
            End Property

            Public ReadOnly Property ExeComplete() As Boolean
                    If Not IsNothing(p) Then
                        Return p.HasExited
                        Return False
                    End If
                End Get
            End Property

            Private Sub New()
            End Sub

            Public Sub New(ByVal fullPathToExe As String)
                Exe = fullPathToExe
            End Sub

            Public Sub StartProcess()
                If IsNothing(p) Then
                    t = New System.Threading.Thread(AddressOf Me.MonitorExe)
                End If
            End Sub

            Private Sub MonitorExe()
                    p = Process.Start(Exe)
                    While Not abort AndAlso Not p.HasExited
                    End While
                    If Not abort Then
                        RaiseEvent ProcessUpdate(Me, New ProcessInfo(Exe, ProcessStatus.Complete, "Complete"))
                        RaiseEvent ProcessUpdate(Me, New ProcessInfo(Exe, ProcessStatus.Aborted, "Aborted"))
                    End If
                Catch ex As Exception
                    RaiseEvent ProcessUpdate(Me, New ProcessInfo(Exe, ProcessStatus.Failed, ex.Message))
                End Try
            End Sub

            Public Sub StopProcess()
                abort = True
            End Sub

        End Class

    End Class

    Author Comment

    Hi gbzhhu,
      I tried using the different threads & the program still froze, I could have been doing it wrong.

    Hi Idlemind,
      I used your while loop & it worked perfect. I think mine wasn't working because I didn't use 'Application.DoEvents()'. I thought that having Refresh() in my loops would keep the GUI updated. I just have to go find out what 'DoEvents' is actually doing.

    Thanks for your help, much appreciated.  

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Looking for New Ways to Advertise?

    Engage with tech pros in our community with native advertising, as a Vendor Expert, and more.

    Suggested Solutions

    I'm currently working for a company where I have to upgrade over 50 VB6 programs to VB.NET 2008.  So far I'm about half way through, and I've learned quite a few tricks that drastically improve the performance of VB.NET apps. Because there are a…
    Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
    Internet Business Fax to Email Made Easy - With eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
    This video discusses moving either the default database or any database to a new volume.

    759 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

    Need Help in Real-Time?

    Connect with top rated Experts

    9 Experts available now in Live!

    Get 1:1 Help Now