program hangs while batch file is running

Posted on 2006-05-24
Medium Priority
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
  • 2
LVL 12

Expert Comment

ID: 16754603
Use threads

System.Threading.Thread class
LVL 12

Expert Comment

ID: 16754618
LVL 86

Accepted Solution

Mike Tomlinson earned 2000 total points
ID: 16755265
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

ID: 16755898
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.  

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Article by: jpaulino
XML Literals are a great way to handle XML files and the community doesn’t use it as much as it should.  An XML Literal is like a String (http://msdn.microsoft.com/en-us/library/system.string.aspx) Literal, only instead of starting and ending with w…
A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?

850 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