我在App.Xaml中有这个:
public App()
{
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += new DoWorkEventHandler(DoBackgroundWork);
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundCompleted);
_backgroundWorker.RunWorkerAsync();
_splashView = new SplashView();
_splashView.Show();
}
DoBackgroundWork
方法执行一些数据库设置,然后BackgroundCompleted
事件关闭_splashView
并显示_mainView
。
但是,从_splashView
修改BackgroundCompleted
中的任何内容都会导致跨线程异常,这就是我设计的后台工作者修复的问题。我猜这与backgroundworker在App.Xaml
中的工作方式有关。也许这是制作启动画面的坏方法?
答案 0 :(得分:0)
后台工作程序使用SynchronizationContext。这是从内存开始的,但我不认为它已在App构造函数中初始化。
在构造BW之前,检查SynchronizationContext.Current不为null。 同时检查SynchronizationContext.Current在构造BW之前和已完成的方法中是相同的。
如果不是,您需要稍后在此过程中移动代码... App.OnStartUp应该没问题
答案 1 :(得分:0)
这可能是制作启动画面的不好方法吗?
除非我误解了你的问题,否则我认为没有必要这样做以显示闪屏。只需选择图像,然后在“属性”窗口中单击BuildAction
下拉列表,然后选择SplashScreen
。此外,我认为您可以通过消除BackgroundWorker
来简化您的流程,除非您的数据功能需要很长时间。我相信你添加了它来容纳启动画面的显示/隐藏。
答案 2 :(得分:-1)
无法保证OnWorkCompleted
的事件处理程序将用于执行哪个线程。
查看类似问题BackgroundWorker OnWorkCompleted throws cross-thread exception
您必须使用Invoke
或BeginInvoke
方法修改后台线程中的可视元素。您可以直接在要修改其属性的对象上调用它,或使用Dispatcher
。
编辑:根据与Adam的谈话
SynchronizationContext
具有在初始线程(而不是BackgroundWorker)上运行OnWorkCompleted
事件处理程序所需的效果。 http://msdn.microsoft.com/en-us/magazine/gg598924.aspx。 (见图2)
如果在SynchronizationContext初始化之前创建并运行BackgroundWorker,则OnWorkCompleted
将在与BackgroundWorker相同的线程上执行。
感谢Adam。