Overview
This method stops the execution of a program until an external application or command started with Process.Start is fully finished. It is useful for synchronous processing, such as reading a file only after it has been extracted or running multiple batch processes in a specific order.
Specifications (Input/Output)
- Input: The process to execute (
Processobject). - Output: The process exit code (
ExitCode) after waiting. - Behavior: Blocks the calling thread until the target process terminates.
Basic Usage
Call the WaitForExit() method on the process instance.
using System.Diagnostics;
// Start Notepad
var proc = Process.Start("notepad.exe");
// Wait here until Notepad is closed
proc.WaitForExit();
// Process after exit
Console.WriteLine("Notepad has been closed.");
Full Code
The following console application executes the Windows ping command, waits for the communication test to finish, and then determines success or failure based on the exit code.
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Console.WriteLine("--- Starting External Process ---");
// 1. Process startup settings
// Command to ping localhost (127.0.0.1) 3 times
// Use "-n" for Windows, and "-c" for Linux/macOS
string fileName = "ping";
string arguments = "127.0.0.1 -n 3";
try
{
// Execute the command using Process.Start
using (Process proc = Process.Start(fileName, arguments))
{
if (proc != null)
{
Console.WriteLine("Executing command... waiting for completion.");
// 2. Wait for the process to exit
// Calling this method prevents the next line from running until the ping command finishes
proc.WaitForExit();
// 3. Verify results
// ExitCode: 0 usually represents a successful termination
Console.WriteLine("-----------------------------");
Console.WriteLine("Process has terminated.");
Console.WriteLine($"Exit Code: {proc.ExitCode}");
if (proc.ExitCode == 0)
{
Console.WriteLine("Result: Success");
}
else
{
Console.WriteLine("Result: Failure or Error");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Startup Error: {ex.Message}");
}
}
}
Execution Result Example
--- Starting External Process ---
Executing command... waiting for completion.
Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Ping statistics for 127.0.0.1:
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
-----------------------------
Process has terminated.
Exit Code: 0
Result: Success
Customization Points
- Setting a Timeout: Specify milliseconds like
proc.WaitForExit(5000)to set a maximum wait time. Since it returnsfalseif the process does not finish within the specified time, actions such as forcing the process to stop (Kill) can be taken. - Asynchronous Waiting (.NET 5+): Using
WaitForExitAsync()allows waiting for termination usingawaitwithout freezing the main thread. This is essential for GUI applications.
Points of Caution
- Avoiding Deadlocks: If standard output or standard error is redirected (
RedirectStandardOutput = true), calling onlyWaitForExit()might cause the buffer to overflow, leading to a deadlock where the process stops indefinitely. In such cases, read the output asynchronously or ensure the reading process is finished before waiting. - Usage in UI Threads: Calling
WaitForExit()inside button events in Windows Forms or WPF causes the entire application to freeze and become “Not Responding.” For apps with a UI, consider asynchronous processing such asTask.RunorWaitForExitAsync.
Application
Waiting with a Timeout
This is a robust implementation example that forcibly terminates the process if it does not finish within the specified time.
using (Process p = Process.Start("notepad.exe"))
{
// Wait for 10 seconds
if (p.WaitForExit(10000))
{
Console.WriteLine("Terminated normally.");
}
else
{
Console.WriteLine("Timed out. Forcing the process to terminate.");
p.Kill(); // Force stop
}
}
Summary
Process.WaitForExit is an essential method for ensuring that tasks proceed in the correct order during batch processing or consecutive command executions. It is highly effective when branching logic based on the exit results of external tools. However, when using it in GUI applications, care must be taken to set timeouts or use asynchronous methods to prevent the application from freezing.
