当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();