Stworzyłem prostą metodę testową w nowej aplikacji, która jest wywoływana po kliknięciu przycisku (tylko) w moim głównym formularzu. Metoda wygląda następująco:
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
Window1 window = new Window1();
window.Closed += (s, a) => window.Dispatcher.InvokeShutdown();
window.Show();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
Window1
jest klasa okna zrobiłem, że nie ma nic, ale jednym TextBlock
na nim. Mogę kliknąć ten przycisk tyle razy, ile chcę, i nadal otwiera nowe okna bez żadnych problemów (niezależnie od tego, czy najpierw zamknę poprzedni).
Podejrzewam, że problem występuje w kodzie, że nie pokazuje nam się gdzieś. Musisz być bardzo ostrożny, aby nic w nowym wątku nie próbowało uzyskać dostępu do dowolnego interfejsu użytkownika związanego z głównym wątkiem. System Windows działający w oddzielnych wątkach nie może komunikować się ze sobą, dopóki nie przejdzie przez moduł rozsyłający drugiego wątku. Wyjątek, który widzisz, jest generowany, gdy dowolna metoda lub właściwość obiektu DispatcherObject jest dostępna z wątku innego niż ten, który utworzył obiekt.
Cofając się, dlaczego ważne jest, aby nowe okno było w swoim wątku? O ile nowe okno nie zmonopolizuje wątku, prawdopodobnie będzie działało dobrze na głównym wątku. Jeśli wykonujesz jakąś długą operację blokowania, być może sama ta operacja powinna zostać przeniesiona do wątku, a nie do całego okna. Nie wiem, co dokładnie robisz, ale to jest coś do przemyślenia.
EDIT: Zdając sobie sprawę, że nie może być uruchomiony w typowej aplikacji WPF (wygląda na to, że możesz być w plugin Office), zaktualizowałem mój test do uruchomienia okna całkowicie samodzielnych na własnych wątkach. Jednak wciąż jestem w stanie uruchomić dwa okna z rzędu bez żadnych problemów.
Oto mój nowy test. Ta metoda i klasa testowa Window1
stanowią całość mojej aplikacji.
[STAThread]
public static int Main(string[] args)
{
ThreadStart threadFunc =() =>
{
Window1 window = new Window1();
window.Closed += (s, a) => window.Dispatcher.InvokeShutdown();
window.Show();
System.Windows.Threading.Dispatcher.Run();
};
Thread thread = new Thread(threadFunc);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
thread = new Thread(threadFunc);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
return 0;
}
Tak, wydaje się, że nic złego z tym, co staramy się robić, nie widzę żadnych oczywistych kwestii w kodzie. Podejrzewam, że w oknie niestandardowym pojawia się jakaś nieważna komunikacja między wątkami, gdy jest wyświetlana. (Albo to albo występuje problem specyficzny dla wtyczek pakietu Office).
Dlaczego chcesz utworzyć nowy wątek, aby wyświetlić to okno? Na ogół nie jest to dobry pomysł. Po drugie, próbowałem tego i działa dobrze (z wyjątkiem tego, że nie mam pojęcia, co robi "LoginCheck"). Gdzie występuje wyjątek? –
Cały powiązany z UI kod musi działać w wątku głównym. Co próbujesz osiągnąć tutaj? – almulo
Zwykle ten błąd odnosi się do próby uzyskania dostępu do właściwości w pierwszym formularzu od tego, który został zerwany. Musimy zobaczyć, co dzieje się w drugim formularzu, który powoduje problem. – DoomVroom