Reputation: 97
I want to:
I'm having problems making this happen. I'm aware of a multitude of posts about this similar issue, but haven't found a solution that works for me.
I have tried:
What would be the neatest, and simplest solution for a simple Windows Form program? There are no extra classes used, and all code is in the Form1 class.
Upvotes: 2
Views: 5982
Reputation: 203847
The Process
class fires an Exited
event when the process exits. You can add a handler to that event to execute code when the process exits without blocking the UI thread:
process.EnableRaisingEvents = true;
process.Exited += (s, args) => DoStuff();
Alternatively you could create a Task
that represents the completion of the process to leverage the TPL for asynchrony:
public static Task WhenExited(this Process process)
{
var tcs = new TaskCompletionSource<bool>();
process.EnableRaisingEvents = true;
process.Exited += (s, args) => tcs.TrySetResult(true);
return tcs.Task;
}
This would allow you to write:
await process.WhenExited();
UpdateUI();
Upvotes: 5
Reputation: 46
You should start process in BackgroundWorker so you can catch complete event on same thread.
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate {
Process proc = Process.Start("YOUR-PROCESS-PATH");
proc.Start();
proc.WaitForExit();
}
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();
then catch the worker ended event on called thread;
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Do your thing o UI thread
}
Upvotes: 1
Reputation: 1306
Here is my favorite way to do something like this with a BackgroundWorker. This has the advantage of the RunWorkerCompleted callback being on the main thread, so it can interact with the UI.
public partial class Form1 : Form
{
...
private BackgroundWorker wrk;
private void button1_Click(object sender, EventArgs e)
{
wrk = new BackgroundWorker();
wrk.DoWork += (s, ea) => { /*Create your process and wait here*/ };
wrk.RunWorkerCompleted += (s, ea) => { textBox1.Text = "Finished"; };
wrk.RunWorkerAsync();
}
}
Upvotes: 2
Reputation: 4797
Here you go:
void Form1_Load(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
var p = Process.Start("notepad.exe");
p.WaitForExit();
}).ContinueWith(antecedant => { MessageBox.Show("Notepad closed"); });
}
Upvotes: 2