Вопрос

So I am trying to make an application that starts a 3rd party exe to do some file operations, based on a list of filenames. So if the list has 13 items I am going through a loop 13 times, each time starting the external process, notifying the user which file is processed right now, starting the process and waiting for it to exit. To notify the user, another listbox is used as a shoutbox. The problem is, that .waitforexit() somehow freezes the whole thread in a strange way, so that the external program is called nmormaly, tyhe files get proccesed normaly but the main window is frozen until all items are done. So basically the Shoutbox is frozen and gets spammed with all the info only after the whole loop is finished. I've tried numerous ways to implement this, such as starting new threads, using threadpool, timers and whatnot. Any help is appreciated. code:

Imports System.Windows.Threading
Imports System.Windows.Forms
Imports System.IO
Imports System.Threading        

If Listbox2.Items.Count > 0 Then
            tabctrl.SelectedIndex = 2
            Listbox3.Items.Add(DateTime.Now.ToString & ": Process initiated.")
            For i = 0 To Listbox2.Items.Count - 1
                Listbox3.Items.Add(DateTime.Now.ToString & ": Processing :" & Listbox1.Items.Item(i))
                If System.IO.File.Exists(Listbox2.Items.Item(i)) = False Then
                    Dim pInfo As New ProcessStartInfo()
                    With pInfo
                        .WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden
                        .FileName = System.IO.Directory.GetCurrentDirectory & "\" & "myapp.exe"
                        .argouments = "w/e"
                    End With
                    Dim p As Process = Process.Start(pInfo)
                    p.WaitForExit()
                    p.Dispose()
                Else
                    Listbox3.Items.Add(DateTime.Now.ToString & ":! " & Listbox2.Items.Item(i) & " already exists. Moving to next file..")
                End If
            Next
            Listbox3.Items.Add("*-*")
            Listbox3.Items.Add(DateTime.Now.ToString & ": Done.")
        End If
Это было полезно?

Решение

The problem is that you (at least in the code you posted) are calling WaitForExit() on the UI thread. The UI thread is responsible for redrawing the window, so if you block it, by calling WaitForExit() for example, its not redrawing the ui and the app appears to be frozen.

What you need to do is call it on another thread or on the thread pool, I recommend using Tasks:

Task.Run( Sub()
  Dim p As Process = Process.Start(pInfo)
  p.WaitForExit()
End Sub)

However, since you're not doing anything with the results of the Process.Start() call, you can also consider not calling WaitForExit() at all.

Since you're using VS2013 you can also use the await operator to wait for the process to finish:

await Task.Run( Sub()
  Dim p As Process = Process.Start(pInfo)
  p.WaitForExit()
End Sub)

Note that you also have to add the async keyword to the surrounding method as well

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top