6

背景:

我正在开发一个 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(); }));
        }
    }
4

1 回答 1

0

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

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

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

于 2013-07-25T14:45:01.430 回答