如何在STA线程上与Bootstrapper同时运行动画SplashScreen

Vla*_*lad 6 c# wpf multithreading mef splash-screen

背景:

我正在开发一个WPF应用程序,它使用MEF框架自动链接应用程序所需的库和组件.随着人们添加自己的组件,在较慢的机器上加载需要0-2秒到6-7秒.为此,我认为一个漂亮的启动画面让用户知道应用程序正在加载是必要的.理想情况下,初始屏幕将显示动画进度条以及描述正在加载哪些组件的状态文本字段.

问题:

我设计了一个启动画面窗口,在应用程序开始时调用(OnStartup),然后加载MEF引导程序.问题当然是,窗口没有动画,因为它与MEF引导程序加载在同一个线程上.我尝试将引导程序放在一个单独的线程上,但它抱怨它不是一个STA线程.即使在STA线程上它仍然不喜欢它并且在尝试加载主应用程序窗口时它会引发错误.我不能把启动画面窗口本身放在一个单独的线程上,因为我无法访问它,它也必须是一个STA线程,因为它是一个UI组件.(意识到这是不真实的,我可以和线程交谈)

更新

我找到了一个解决方案,我将启动画面窗口保存在一个单独的STA线程中.谢谢大家的回复,指出我正确的方向:

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        Dispatcher threadDispacher = null;
        Thread thread = new Thread((ThreadStart)delegate
        {
            threadDispacher = Dispatcher.CurrentDispatcher;
            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(threadDispacher));

            loadingWindow = new LoadingWindow();
            loadingWindow.Closed += (s, ev) => threadDispacher.BeginInvokeShutdown(DispatcherPriority.Background);
            loadingWindow.Show();

            System.Windows.Threading.Dispatcher.Run();
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = true;
        thread.Start();

        var bootstrapper = new Bootstrapper();
        bootstrapper.Run();

        if (threadDispacher != null)
        {
            threadDispacher.BeginInvoke(new Action(delegate { loadingWindow.Close(); }));
        }
    }
Run Code Online (Sandbox Code Playgroud)

Tim*_*ote 0

您正在以正确的方式将引导程序移动到它自己的线程中。但是,您应该做的是确保需要在 UI 线程上执行的部分也在UI 线程上调用

因此,当 MEF 引导程序完成后,您可以在主线程上调用隐藏启动窗口并打开主窗口,甚至可以从 MEF 线程调用。

将消息传递到主线程的一种方法是通过调度程序