背景:
我正在开发一个WPF应用程序,它使用MEF框架自动链接应用程序所需的库和组件。通过添加自己的组件,在速度较慢的机器上加载所需的时间从0-2秒到6-7秒不等。为此,我认为需要一个漂亮的启动屏幕,让用户知道应用程序正在加载。理想情况下,启动屏幕将显示一个动画进度条以及一个状态文本字段,描述正在加载哪些组件。
问题:
我设计了一个启动屏幕窗口,这个窗口在应用程序(OnStartup)开始时被称为“启动窗口”,然后是加载MEF。当然,问题是,由于窗口与MEF引导程序加载在同一个线程上,所以窗口没有动画。我试着将引导程序放在单独的线程上,但它抱怨说它不是STA线程。即使在STA线程上,它仍然不喜欢它,并且在加载主应用程序窗口时会抛出错误。我不能将splash屏幕窗口本身放在单独的线程上,因为这样我就无法访问它,而且它必须是STA线程,也因为它是UI组件。(意识到这是不对的,我可以和线程交谈)
更新
我找到了一个解决方案,我在一个单独的STA线程中保留了splash窗口。谢谢每一个回答我的人指出了正确的方向:
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(); }));
}
}发布于 2013-07-25 14:45:01
你把引导程序移到自己的线程上是正确的。但是,您应该确保需要在UI线程上执行的部分也是在UI线程上调用的。
因此,当MEF引导程序完成后,您可以调用splash窗口的隐藏和主线程上主窗口的打开,甚至可以从MEF的线程中调用。
将消息传递到主线程的一种方法是通过调度员
https://stackoverflow.com/questions/17861189
复制相似问题