C# 在WPF中创建和更改初始屏幕

C# 在WPF中创建和更改初始屏幕,c#,wpf,multithreading,splash-screen,C#,Wpf,Multithreading,Splash Screen,我有以下代码: Thread thread = new Thread(new ThreadStart(CreateSplashScrn)); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); OpenSplashScrn(); ChangeSplashScrnMessageText("String")

我有以下代码:

 Thread thread = new Thread(new ThreadStart(CreateSplashScrn));
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();

    OpenSplashScrn();
    ChangeSplashScrnMessageText("String");

    public void CreateSplashScrn()
    {
        splash = new SplashScreen(this);
        System.Windows.Threading.Dispatcher.Run();
    }

    public void OpenSplashScrn()
    {
        splash.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
            new Action(() => { splash.Show(); }));
    }

    public void ChangeSplashScrnMessageText(string messageText)
    {
        splash.messageLabel.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
            new Action(() => { splash.messageLabel.Content = messageText; }));
    }
但是,这会在OpenSplashScrn()处返回空引用异常。 我如何在另一个线程中打开它并更改标签内容?
这在一项任务中是可能的吗

您不应该在后台线程中打开splach屏幕并在UI线程中执行长时间运行的初始化

var splash = new SplashScreen(this);
splash.Show(); 

Thread thread = new Thread(new ThreadStart(Initialize));
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();


public void Initialize()
{
    //move your long running logic from your app here..
    ChangeSplashScrnMessageText("Initialization Started");
    Thread.Sleep(1000);
    ChangeSplashScrnMessageText("Initialize finished");
}

public void ChangeSplashScrnMessageText(string messageText)
{
    splash.messageLabel.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
        new Action(() => { splash.messageLabel.Content = messageText; }));
}
您应该在UI线程中打开启动屏幕,并在非UI线程中执行长时间运行的初始化

var splash = new SplashScreen(this);
splash.Show(); 

Thread thread = new Thread(new ThreadStart(Initialize));
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();


public void Initialize()
{
    //move your long running logic from your app here..
    ChangeSplashScrnMessageText("Initialization Started");
    Thread.Sleep(1000);
    ChangeSplashScrnMessageText("Initialize finished");
}

public void ChangeSplashScrnMessageText(string messageText)
{
    splash.messageLabel.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
        new Action(() => { splash.messageLabel.Content = messageText; }));
}
编辑:为什么不在其他线程中打开启动屏幕?

因为它使日志中的事情复杂化,99%的情况下没有理由这样做。您可以在单线程中运行多个窗口,但仍可以在后台执行一些长时间运行的任务


我猜,在主窗口中,您正试图在UI线程中执行长时间运行的任务。只需将其移动到后台线程…

为什么要在另一个线程中打开启动屏幕?谢谢,但从UI启动时,这将如何工作?@Jackson30:我编写了一个示例,假设您从UI线程启动它。在你的问题中更好地描述你对用户的POVSorry有什么期望我的意思是从另一个线程而不是UI启动启动屏幕thread@CameronMacFarland:在他的示例中,两个线程都是UI线程,而在我的示例中不是。即使假设你提到他的例子,我所有的主张都是有效的,不是吗?虽然从技术上讲,在后台线程中运行UI(IsBackground=True)可能是可行的,但我要区分这两种情况,因为在后台运行的UI线程看起来很矛盾。@Jackson30:我说了你:你不应该从UI线程以外的其他线程启动启动启动屏幕。