Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF open new window on another thread

In the code below, I call method that opens a custom new window. However when application is doing some long running task I wish to still be able to activate the window. Is it possible to do it on another thread or by using the Task class?

public static class CustomW
{
    static Custom_Window_Chrome_Demo.ThemedWindow MsgBox(string Msgbx_TTL, string Msgbx_Contnt)
    {
        var w_mbx = new Custom_Window_Chrome_Demo.ThemedWindow();
        w_mbx.Width = 950; w_mbx.Height = 159;
        w_mbx.Title = Msgbx_TTL;

        Grid g = new Grid();
        StackPanel spM = new StackPanel();
        TextBlock TblckErrMsg = new TextBlock();
       //more settings......
    } 
}

This is how I tried to invoke it,

public void newMsgBoxShow(string Msgbx_TTL, string Msgbx_Contnt)
{
    System.Threading.Thread s = new System.Threading.Thread( 
       ()=>
        CustomW.MsgBox(Msgbx_TTL, Msgbx_Contnt).Show()
       );
}

but when I am using the new thread I am getting the following error.

The calling thread must be STA, because many UI components require this

What is the correct way to achieve the required result ?

like image 501
PblicHieip Hag Ana Avatar asked Dec 03 '25 15:12

PblicHieip Hag Ana


2 Answers

Use this:

 Task.Factory.StartNew(new Action(() =>
            {
                //your window code
            }), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());

When new thread is created with Current Synchronization context it will be able to update the UI.(when current thread is UI thread)

You can also use dispatcher to execute your code.

 System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(()=>
            {
                //your window code
            }));
like image 72
Kylo Ren Avatar answered Dec 06 '25 05:12

Kylo Ren


Take a look at Dispatcher
https://msdn.microsoft.com/cs-cz/library/system.windows.threading.dispatcher%28v=vs.110%29.aspx

Dispatcher.CurrentDispatcher.Invoke(delegate { /* CODE */ }, DispatcherPriority.Normal);
like image 39
Daniele Hošek Avatar answered Dec 06 '25 04:12

Daniele Hošek