Search code examples
c#wpfmultithreadingwindowsta

Window closes immediately after being created (and shown) in a sepatarted thread


I was trying to instantiate and show a Window, when I got an exception saying {"The calling thread must be STA, because many UI components require this."} so I re-did it all in a separated STA thread as follows :

var thread = new Thread(() =>
{
     notificationPopUp = new NotificationPopUpView(unreadNotifications.First().session_s,unreadNotifications.First().secondry_msg);
     notificationPopUp.Show();
});

thread.SetApartmentState(ApartmentState.STA);
thread.Start();

Now the window shows and then goes away immediately, I suppose that is because the thread terminated its work so than the object declared within died as well, well if I'm correct, how should I deal with this, I tried to avoid this solution by putting the [STAThread] attribute before the Main method, before the owner method, before many other methods (desperately) but I continued to have the same problem, I know the Title of the question is somehow not well descriptive, but I'm kinda obliged to mention this STA thing, here's the error I used to get before creating the thread (just to provide you with the whole data) :

enter image description here

So my principle question is : Why is the window closing immediately ?

Now if because it's because it's created in the thread and it gets disposed after the thread finishes working, what should I do knowing that I should keep respecting the STA Thread caller ? thanks in advance.


Solution

  • Well, you have created a window in new thread, and the thread terminates, then who is going to run the message loop?

    A thread, which created a user object(Window, Form, Control) must run its message loop to respond to the messages sent by the operating system.

    Call Dispatcher.Run to run the message loop.

    var thread = new Thread(() =>
    {
        notificationPopUp = new NotificationPopUpView(unreadNotifications.First().session_s,unreadNotifications.First().secondry_msg);
        notificationPopUp.Show();
        Dispatcher.Run();
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.IsBackground = true;
    thread.Start();