1

非モデル ウィンドウ (WPF) をいくつか開きたいのですが、これが発生する必要がある時点で、非 STA スレッドを使用しています。だから私は新しいスレッドを開始し、そこでそれらを開きます。しかし、開くとすぐに再び閉じます。(ちなみに、これらのウィンドウの動作はメインウィンドウから独立している必要があります。したがって、所有者プロパティは設定されていません)

private void SomeMethod_OnA_NON_STA_Thread()
{
    // some other work here

    Thread ANewThread = new Thread(OpenSomeWindows);
    ANewThread.SetApartmentState(ApartmentState.STA);
    ANewThread.Start();
}


private void OpenSomeWindows()
{
    TestWindow T;

    for (int i = 0; i < 3; i++)
    {
        T = new TestWindow();
        T.Show();
    }
}

ここで何が間違っていますか?

4

2 に答える 2

3

ウィンドウを有効にしたい場合は、ウィンドウを作成した後にメッセージ ループを開始する必要があります (そうしないと、スレッドが終了するだけで、ウィンドウがレンダリングされる機会がありません)。

private void OpenSomeWindows()
{
    for (int i = 0; i < 3; i++)
    {
        TestWindow T = new TestWindow();
        T.Show();
    }
    Dispatcher.Run(); // <---------
}

(メイン スレッドでは、フレームワークによってメッセージ ループが作成されます。)

PS: ウィンドウをガベージ コレクションできるかどうかはわかりません。そのため、ウィンドウへの参照をどこかに保持します。

List<TestWindow> windows = new List<TestWindow>();
for (int i = 0; i < 3; i++)
{
    TestWindow t = new TestWindow();
    t.Show();
    windows.Add(t);
}
Dispatcher.Run();

PPS: ウィンドウをメインスレッドで実行したいですか? 実際、これを行うことができます。必要なものは次のとおりです。

private void SomeMethod_OnA_NON_STA_Thread()
{
    // some other work here
    Application.Current.Dispatcher.Invoke(OpenSomeWindows);
}

private void OpenSomeWindows()
{
    for (int i = 0; i < 3; i++)
    {
        TestWindow T = new TestWindow();
        T.Show();
    }
    // this way, no Dispatcher.Run is needed
}
于 2011-06-01T15:30:00.730 に答える
0

スレッドは、呼び出しメソッドの最後で終了します。フィールドANewThreadにする(クラス/フォームレベルで宣言する)。

于 2011-06-01T15:29:28.833 に答える