当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问题     
解决方案是使用多线程 首先添加: 使用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();
    

要回复问题请先登录注册