当process.WaitForExit()时,Visual C#GUI停止响应; 用来

我正在使用Visual C#2005(net framework 2)创建一个GUI应用程序。 我使用以下代码来启动一个过程:

Process process = new Process(); process.StartInfo = new ProcessStartInfo("app.exe"); process.StartInfo.WorkingDirectory = ""; process.StartInfo.Arguments = "some arguments"; process.Start(); process.WaitForExit(); 

我希望我的应用程序等到这个过程完成,所以我使用了WaitForExit。 但是当app.exe运行时,GUI Windows会冻结。 我希望它响应(例如按下取消按钮),但我不希望代码继续,因为还有另一个进程要启动。 提前致谢!

您可以捕获Process类的Exited事件:

 void someMethod() { //...possibly more code here Process process = new Process(); process.StartInfo = new ProcessStartInfo("app.exe"); process.StartInfo.WorkingDirectory = ""; process.StartInfo.Arguments = "some arguments"; process.Exited += new EventHandler(ProcessExited); process.Start(); } void ProcessExited(object sender, System.EventArgs e) { //Handle process exit here } 

您等待应用程序的唯一线程上的进程,该线程还负责处理所有GUI事件。 如果你想等待某个事件(比如其他一些进程完成)并且仍然通知你的代码,那么你必须等待另一个线程或使用事件处理程序。

这应该有所帮助。 基本上对于Windows窗体和像这样的简单任务,BackgroundWorker很方便。 下面是一些简单的代码,用于启动记事本并等待它关闭,或者用户可以通过单击取消来杀死它。

  public Form1() { InitializeComponent(); backgroundWorker1.WorkerSupportsCancellation = true; } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { Process process = new Process(); process.StartInfo = new ProcessStartInfo("notepad.exe"); process.Start(); while (!process.HasExited) { if (backgroundWorker1.CancellationPending) { process.Kill(); continue; } else Thread.Sleep(1000); } } private void Start_Click(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } private void Cancel_Click(object sender, EventArgs e) { backgroundWorker1.CancelAsync(); } 

要在Exited事件上接收回调,必须将EnableRaisingEvents设置为true。

 Process correctionProcess = Process.Start(startInfo); correctionProcess.EnableRaisingEvents = true; correctionProcess.Exited += new EventHandler(ProcessExited); 

使用exited对我来说效果很好,并且给了我很大的灵活性,可以顺序运行,部分同步运行,也可以一次运行 – 无需锁定UI。

也许您应该使用BackgroundWorker实现解决方案。 它很容易实现,并做你想要的。

您需要做的是在表单中添加BackgroundWorker的实例,并从BackgrondWorker RunWorkerAsync方法调用运行App.exe的进程。 然后,您可以监视CancelationPending属性以停止进程,或者监视RunWorkerCompleted事件以在进程退出后执行任何必要的操作。

有关BackgroundWorker取消的另一个SO问题

解决方案是使用multithreading启动添加:

使用System.Threading;

然后看下面的代码:

  Process process = new Process(); process.StartInfo = new ProcessStartInfo("app.exe"); process.StartInfo.WorkingDirectory = ""; process.StartInfo.Arguments = "some arguments"; 

//启动一个启动进程的新线程,因此当您调用WaitForExit时,它不会冻结主线程

  Thread th= new Thread(() => { process.Start(); process.WaitForExit(); }); th.Start(); 

如果你想要背靠背地运行多个进程,那么另一种情况是你需要使用类似进程列表的东西看下面的代码

  List processes = new List();; Process process = new Process(); process.StartInfo = new ProcessStartInfo("app.exe"); process.StartInfo.WorkingDirectory = ""; process.StartInfo.Arguments = "some arguments"; processes.Add(process); 

//我手动添加另一个,但你可以使用循环例如

  Process process2 = new Process(); process.StartInfo = new ProcessStartInfo("app.exe"); process.StartInfo.WorkingDirectory = ""; process.StartInfo.Arguments = "some arguments"; processes.Add(process2); 

//然后你将通过你的线程启动它们,第二个进程将等到第一个进程完成而不阻塞UI

  Thread th= new Thread(() => { for (int i = 0; i < processes.Count; i++) { processes[i].Start(); processes[i].WaitForExit(); } }); th.Start();