[C#] Waiting for an External Process to Complete

目次

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 (Process object).
  • 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 returns false if 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 using await without 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 only WaitForExit() 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 as Task.Run or WaitForExitAsync.

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.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次