ApplicationContextクラスを継承することで、アプリケーションスレッドの終了条件を定義する事ができる。 Application.Run()メソッドにApplicationContextクラスから派生したインスタンスを渡すことによりメッセージループの実行が開始する。 ApplicationContext.ExitThread()メソッドを呼び出すことでメッセージループの実行を終了することができる。

このクラスのインスタンスを用いてアプリケーションを開始することにより、ウィンドウを持たないアプリケーションでもメッセージループを持つことができるようになる。 MainFormプロパティを設定することによりウィンドウを持つこともできるが、ウィンドウが閉じてもExitThread()メソッドを呼び出さない限りメッセージループは終了せず、Application.Run()の呼び出しも終了しない。

この例ではApplicationContextを継承したCalculatingApplicationというクラスを作成し、アプリケーションを起動している。 また、計算が終了した時点でクラス内からExitThread()メソッドを呼び出している。 これが呼び出された時点でアプリケーションが終了する。

public class CalculatingApplication : System.Windows.Forms.ApplicationContext {
    public CalculatingApplication() : base() {}

    public void Start()
    {
        // 計算を行うスレッドを起動する
        System.Threading.Thread thread = new System.Threading.Thread( new System.Threading.ThreadStart( Calculate ) );

        thread.Start();
    }

    private void Calculate()
    {
        Console.WriteLine( "計算を開始します。" );

        int count = 0;

        do {
            count += 1;

            System.Threading.Thread.Sleep( 50 );

        } while ( !( 100 < count ) );

        // スレッドのメッセージループを終了する
        this.ExitThread();

        Console.WriteLine( "計算が終了しました。" );
    }

    protected override void ExitThreadCore()
    {
        Console.WriteLine( "スレッドのメッセージループを終了します。" );

        base.ExitThreadCore();
    }
}

public class MainClass {
    static void Main()
    {
        CalculatingApplication app = new CalculatingApplication();

        // 計算を開始する
        app.Start();

        Console.WriteLine( "現在のスレッドでメッセージループが開始されます。" );

        // CalculatingApplicationクラスのインスタンスを使用してアプリケーションを起動する
        System.Windows.Forms.Application.Run( app );

        Console.WriteLine( "スレッドのメッセージループは終了しました。" );
    }
}
Public Class CalculatingApplication

    Inherits System.Windows.Forms.ApplicationContext

    Public Sub New()

        MyBase.New()

    End Sub

    Public Sub Start()

        ' 計算を行うスレッドを起動する
        Dim thread As New System.Threading.Thread(AddressOf Calculate)

        thread.Start()

    End Sub

    Private Sub Calculate()

        Console.WriteLine("計算を開始します。")

        Dim count As Integer = 0

        Do

            count += 1

            System.Threading.Thread.Sleep(50)

        Loop Until (100 < count)

        ' スレッドのメッセージループを終了する
        MyClass.ExitThread()

        Console.WriteLine("計算が終了しました。")

    End Sub

    Protected Overrides Sub ExitThreadCore()

        Console.WriteLine("スレッドのメッセージループを終了します。")

        MyBase.ExitThreadCore()

    End Sub

End Class

Public Class MainClass

    Shared Sub Main()

        Dim app As New CalculatingApplication

        ' 計算を開始する
        app.Start()

        Console.WriteLine("現在のスレッドでメッセージループが開始されます。")

        ' CalculatingApplicationクラスのインスタンスを使用してアプリケーションを起動する
        System.Windows.Forms.Application.Run(app)

        Console.WriteLine("スレッドのメッセージループは終了しました。")

    End Sub

End Class
出力結果
現在のスレッドでメッセージループが開始されます。
計算を開始します。
スレッドのメッセージループを終了します。
スレッドのメッセージループは終了しました。
計算が終了しました。
Press any key to continue