【问题标题】:Creating and changing splash screen in WPF在 WPF 中创建和更改启动画面
【发布时间】:2016-01-18 13:41:30
【问题描述】:

我有以下代码:

 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() 处返回空引用异常。 如何在另一个线程中打开它并更改标签内容? 这可以通过任务完成吗?

【问题讨论】:

  • 为什么要在另一个线程中打开闪屏?

标签: c# wpf multithreading splash-screen


【解决方案1】:

您不应在后台线程中打开启动画面并在 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; }));
}

编辑:为什么不应该在另一个线程中打开启动画面?

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

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

【讨论】:

  • 谢谢,但是从 UI 启动它会如何工作?
  • @Jackson30:假设您从 UI 线程启动它,我已经编写了示例。在您的问题中更好地描述您对用户 POV 的期望
  • 对不起,我的意思是从另一个线程而不是 UI 线程启动启动画面
  • @CameronMacFarland:在他的示例中,两个线程都是 UI 线程,而不是在我的示例中。即使假设您参考了他的示例,我的所有主张都是有效的,不是吗?尽管在后台线程中运行 UI 在技术上可能是可行的 (IsBackground=True),但我会区分这两者,因为在后台运行的 UI 线程看起来很矛盾。
  • @Jackson30:我说你:你不应该从另一个线程而不是 UI 线程启动启动画面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
  • 2020-10-16
  • 2012-02-23
  • 1970-01-01
相关资源
最近更新 更多