我正在使用Visual C#2005(网络框架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会冻结。我希望它响应(例如按下取消按钮),但我不希望代码继续,因为还有另一个进程要启动。提前谢谢!
答案 0 :(得分:5)
您可以捕获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
}
答案 1 :(得分:4)
您正在等待应用程序的唯一线程上的进程,该线程还负责处理所有GUI事件。如果你想等待某个事件(比如其他一些进程完成)并且仍然通知你的代码事件,那么你必须等待另一个线程或使用事件处理程序。
答案 2 :(得分:3)
这应该有所帮助。基本上对于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();
}
答案 3 :(得分:2)
为了在Exited事件上接收回调,必须将EnableRaisingEvents设置为true。
Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited);
使用exited对我来说效果很好,并且给了我很大的灵活性,可以顺序运行,部分同步运行,也可以一次运行 - 无需锁定UI。
答案 4 :(得分:1)
也许您应该使用BackgroundWorker实施解决方案。它很容易实现,并做你想要的。
您需要做的是在表单中添加BackgroundWorker的实例,并从BackgrondWorker RunWorkerAsync方法调用运行App.exe的进程。然后,您可以监视CancelationPending属性以停止进程,或者监视RunWorkerCompleted事件以在进程退出后执行任何必要的操作。
还有另一个SO question,涉及BackgroundWorker取消
答案 5 :(得分:0)
解决方案是使用多线程 首先添加:
使用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<Process> processes = new List<Process>();;
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();