在WPF中创建和更改启动画面

时间:2016-01-18 13:41:30

标签: c# wpf multithreading splash

我有以下代码:

 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()中返回Null Reference Exception。 如何在另一个线程中打开它并更改标签内容? 这可能超过任务吗?

1 个答案:

答案 0 :(得分:0)

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

您应该在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; }));
}

编辑:为什么你不应该在另一个帖子中打开Splash Screen?

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

我想,在你的主窗口中,你试图在UI线程中执行长时间运行的任务。只需将其移至后台线程......