0

我的 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.

但是,修改_splashViewfrom中的任何内容BackgroundCompleted都会导致跨线程异常,我认为这是后台工作人员旨在解决的问题。我猜这与 backgroundworker 的工作方式有关App.Xaml。也许这是做启动画面的坏方法?

4

3 回答 3

0

后台工作人员使用 SynchronizationContext。这是从内存中获取的,但我认为它没有在 App 构造函数中初始化。

在构造 BW 之前,请检查 SynchronizationContext.Current 是否为空。还要检查 SynchronizationContext.Current 在构造 BW 之前和完成方法中是否相同。

如果不是,您需要稍后在此过程中移动代码... App.OnStartUp 应该没问题

于 2013-01-07T19:31:57.670 回答
0

也许这是做启动画面的坏方法?

除非我误解了您的问题,否则我认为没有必要这样做来显示启动画面。只需选择图像,然后在“属性”窗口中单击BuildAction下拉菜单并选择SplashScreen. 另外,我认为您可以通过消除 来简化流程BackgroundWorker,除非您的数据功能需要很长时间。我相信您添加它是为了适应启动画面的显示/隐藏。

于 2013-01-07T19:43:44.557 回答
-1

无法保证哪个线程的事件处理程序OnWorkCompleted将用于执行。

见类似问题BackgroundWorker OnWorkCompleted throws cross-thread exception

您必须使用InvokeBeginInvoke方法从后台线程修改可视元素。您可以直接在要修改其属性的对象上调用它,或者使用Dispatcher.

编辑:根据与亚当的对话

对在初始线程(而不是 BackgroundWorker 的)上运行的事件处理程序SynchronizationContext具有预期的效果。http://msdn.microsoft.com/en-us/magazine/gg598924.aspx。(见图2)OnWorkCompleted

如果 BackgroundWorker 是在 SynchronizationContext 初始化之前创建并运行的,那么OnWorkCompleted它将在可能与 BackgroundWorker 相同的线程上执行。

谢谢亚当。

于 2013-01-07T19:22:27.383 回答