HOWTO · Csharp

C# でコンソールアプリケーションを終了する

C# のコンソールアプリケーションは、Main から return 文で戻ると通常の実行を終えます。別のメソッドからプロセスを直ちに終了するには、Environment.Exit() メソッドを呼び出します。

このページの内容

C# のコンソールアプリケーションは、処理が完了したら Main から戻って終了します。別のメソッドからプロセスを直ちに終了する必要がある場合に限り、Environment.Exit() を使います。Main から整数を返すか、Environment.Exit(int) に整数を渡すと、プロセスの終了コードが設定されます。コンソールに表示するテキストは終了コードとは別です。

Main から戻ってアプリケーションを終了する

return 文は現在のメソッドを終了します。Main が終了すると、アプリケーションの通常の実行も終了し、return の後にある文は実行されません。入れ子になったメソッドから戻る場合は呼び出し元に制御が戻るだけなので、それだけでアプリケーションが終了するわけではありません。通常の完了には Main から戻る方法を使いましょう。通常の制御フローに沿って終了するため、周囲の finally ブロックやリソースのクリーンアップが実行されます。

void Main() では、値を返さずに終了するために return; を使えます。int Main() では終了コードを返せます。この完全な例は状態を示す行を表示し、慣例上の成功コードを返します。提供された実行結果では Work completed. が表示され、終了コードは 0 でした。この表示は英語のままです。

この例を実行します。

using System;

class Program
{
    static int Main()
    {
        Console.WriteLine("Work completed.");
        return 0;
    }
}
Work completed.

return 0; は Main を終了し、オペレーティングシステムまたは呼び出し元のプロセスに 0 を返します。失敗を示すには、代わりにゼロ以外のコードを返します。ゼロ以外の各値が何を意味するかは、プログラムまたは呼び出し元が定義します。

Environment.Exit() を使って任意のメソッドから終了する

Environment.Exit(int) を使うと、Main 以外のメソッドからプロセスを終了できます。指定した整数の終了コードでプロセスを直ちに終了し、呼び出し元には戻りません。意図的に即時終了させる場合など、通常の巻き戻しを利用できない状況に限って使いましょう。通常のエラー処理では、問題を報告して Main から適切なコードを返す方法が一般的です。

この完全な例では、Main 以外のメソッドである StopApplication から Environment.Exit(0) を呼び出します。

このセクションのコードと表示されるラベルや出力は英語のままです。

using System;

class Program
{
    static void Main()
    {
        StopApplication();
        Console.WriteLine("This line is not reached.");
    }

    static void StopApplication()
    {
        Console.WriteLine("Stopping now.");
        Environment.Exit(0);
    }
}

この呼び出しは終了コード 0 を渡して、StopApplication が戻る前にプロセスを終了するため、Main の次の行には到達しません。提供された実行結果は上記の Main の例に対するもので、この例の実行結果ではありません。たとえば Environment.Exit(1); と呼び出すと、終了コード 1 が渡されます。この整数はオペレーティングシステムまたは呼び出し元のプロセスに渡され、Console.WriteLine で表示するメッセージとは別です。このメソッドは System.Environment の静的メソッドなので、using System; を使うファイルから直接呼び出せます。

終了コードを選び、クリーンアップへの影響を理解する

慣例として、成功には 0、失敗にはゼロ以外の値を使います。ただし、これはすべてのアプリケーションに共通する固定の対応付けではありません。スクリプト、サービスマネージャー、その他の呼び出し元が解釈する必要のあるコードは、説明を記録してください。Main から整数を返す方法と Environment.Exit(int) を呼び出す方法は、どちらもプロセスの終了コードを伝えます。どちらの値も自動的には表示されないため、利用者に理由を伝える必要がある場合は、診断メッセージを別に出力します。

プログラムが通常どおり終了できる場合は、Main から戻る方法を優先してください。メソッドから通常どおり戻ると、制御が try 文を抜ける際に finally ブロックが実行され、using 宣言などのスコープ付きリソースもスコープの終了時に破棄されます。Environment.Exit() はプロセスを直ちに停止するため、通常のスタック巻き戻しは行われず、未実行の finally ブロックやマネージドリソースのクリーンアップも省略されます。即時終了を使う前に、通常の制御フローで重要なリソースをフラッシュまたはクローズしてください。データの保全やリソースの解放にクリーンアップが必要な場合は、即時終了を避けます。

プロセス終了とループの break、例外、Ctrl+C を区別する

break 文は最も内側にあるループまたは switch を抜けます。その構造の後から実行が続きます。ループを抜けた後にプログラムを終了したい場合は、Main の末尾まで実行するか、ループの後で Main から戻ります。

例外をスローすると、制御は一致するハンドラーに移ります。ハンドラーが例外を捕捉して実行が続く場合、プロセスは終了していません。アプリケーションを終了する必要がある場合は、状況を処理したうえで、通常の戻り方と適切な終了コードを選びます。未処理の例外によってプロセスが終了することはありますが、終了の近道として例外を使うと、意図した制御フローやエラー処理が分かりにくくなります。

Ctrl+C はコンソールからのキャンセル要求であり、正常終了を保証するコマンドではありません。プログラムは Console.CancelKeyPress を通じて要求を検知できます。プロセスが直ちに停止するか、ハンドラーが既定の応答を取り消すかは、イベントの処理方法とホスト環境によって異なります。キャンセル時にクリーンアップが必要なら、要求を記録し、メインの制御フローで処理を止めて通常どおり戻るようにします。