Как предотвратить закрытие немодальных окон в новом потоке STA - PullRequest
1 голос
/ 01 июня 2011

Я хочу открыть некоторые немодельные окна (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();
    }
}

Что я здесь не так делаю?

Ответы [ 2 ]

3 голосов
/ 01 июня 2011

Если вы хотите, чтобы ваши окна работали, вы должны запустить цикл обработки сообщений после того, как вы их создали (в противном случае ваш поток просто закрывается, и окна не имеют возможности визуализировать себя):

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
}
0 голосов
/ 01 июня 2011

Поток умирает в конце вызывающего метода. Сделайте ANewThread в поле (объявите его на уровне класса / формы).

...