Press "Enter" to skip to content

U mnie działa – ale tylko pod debuggerem

Jedną z zalet tego, jak coś się robi jest to, że czasami coś udaje że działa. A jak to mówi mój wybranek życiowy – „Jak coś czasami nie działa, to to nie działa”. Także piszę sobie kod uczelniany typowo, i w którymś momencie, ten wg mnie „skończony” projekt próbuję odpalić poza debuggerem. I tak zaczyna się moja historia, bo okazuje się, że to NIE działa. No chyba że uruchomię poza debuggerem i potem debugger podepnę.


Tak czy inaczej działało, a potem podpięłam najprostszy możliwy panel logowania. Nowe wpfowe okno, textbox, passwordbox, 2 textblocki, przycisk OK. Potem użyłam tego mniej więcej tak:

   protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            loginWindow = new LoginWindow(Parameters);
            loginWindow.ShowDialog();
            IContainer container = bootstrapper.Bootstrap();
            var mainViewModel = container.Resolve<MainViewModel>();
            MainWindow = new MainWindow(mainViewModel);
            MainWindow.Show();
            mainViewModel.Load();
        }

No i problem był taki, że o ile pod debuggerem pojawiało mi się drugie okno, to poza już nie. Dlaczego?

Nie, to nie prism czy tam autofac popsuł, choć początkowo to ich obwiniłam. Po prostu między zamknięciem okienka z logowaniem a otwarciem głównego okienka z aplikacją minęło kilka cykli (które były potrzebne aby się rzekomi winowajcy przygotowali się do roboty) a WPF domyślnie jak nie wyświetla żadnego okna to ubija aplikację. Czasami się zdarzy, że zacznie ubijać w trakcie otwierania już okienka i mamy InvalidOperationException z takim stack tracem

at System.Windows.Application.GetResourcePackage(Uri packageUri) at System.Windows.Application.GetResourceOrContentPart(Uri uri) at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) at Drawing.MoleculeView.InitializeComponent() in (…)

i tak go skubańca złapałam (dla osób co jeszcze próbują zabrnąć w tą ślepą uliczkę i się uczą WPFa w 2019 nadmienię, że wystarczy w app.xaml do Application dodać

DispatcherUnhandledException="App_OnDispatcherUnhandledException"

zaimplementować zrzucając exception gdzie bądź, przy appkach na własne potrzeby może być nawet do

MessageBox.Show(e.Exception.Message+e.Exception.GetType().FullName+e.Exception.StackTrace);

jak w moim przypadku.

Skoro już to mamy, to sprawa prosta – tak, wpfie, wiem że przez mniej niż sekundę żadnego okna nie ma, więc daruj sobie śledzenie otwartych okien (ShutdownMode=”OnExplicitShutdown”

w Application z app.xaml) ale pozwól, że to ja ci powiem kiedy masz się ubić – tj w głównym oknie dać to:

 protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            App.Current.Shutdown(); // dodać to
        }

Teraz działa wszędzie.

2 komentarze

  1. U mnie działa – ale tylko pod debuggerem

    Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl

  2. Cepewka Cepewka

    Ja dla pewności zaczynam od czegoś takiego:

    AppDomain.CurrentDomain.UnhandledException += delegate (object sender, UnhandledExceptionEventArgs e)
    {
    Log(„Unhandled exception”, e.ExceptionObject);
    };

    System.Windows.Application.Current.DispatcherUnhandledException += delegate (object sender, DispatcherUnhandledExceptionEventArgs e)
    {
    Log(„Unhandled dispatcher exception”, e.Exception);
    };

    System.Windows.Forms.Application.ThreadException += delegate (object sender, ThreadExceptionEventArgs e)
    {
    Log(„Thread exception”, e);
    };

    Dispatcher.UnhandledException += delegate (object sender, DispatcherUnhandledExceptionEventArgs e)
    {
    Log(„Dispatcher unhandled exception”, e.Exception);
    };

    TaskScheduler.UnobservedTaskException += delegate (object sender, UnobservedTaskExceptionEventArgs e)
    {
    Log(„Unobserved task exception”, e.Exception);
    };

Comments are closed.