问题描述
WPF-我正在使用BackgroundWorker创建Model3D对象,但是当我要将其添加到XAML中定义的Model3DGroup时,出现异常:
这是后面的全部代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
GeometryModel3D geometryModel3D = (GeometryModel3D)e.Result;
model3DGroup.Children.Add(geometryModel3D);
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
GeometryModel3D geometryModel3D = new GeometryModel3D();
e.Result = geometryModel3D;
}
}
这就是整个XAML:
<Grid>
<Viewport3D Margin="4,4,4,4" Grid.Row="0" Grid.Column="0">
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup x:Name="model3DGroup">
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
在RunWorkerCompleted处理程序中,您要将GeometryModel3D实例添加到Model3DGroup中,该实例显然是在UI线程之外的其他线程中创建的,因为BackgroundWorker.DoWork处理程序在单独的线程中执行.
简而言之,WPF不允许这样做,正如您可能从异常消息中注意到的那样.所有UI元素,或更确切地说,都是 DispatcherObject 应用程序中的/派生对象必须在同一线程中创建.获取WPF的概述线程模型,并参阅 BackgroundWorker 文档中的备注部分.
>但是,您可以通过同步调用 Dispatcher 来创建新的GeometryModel3D实例您的MainWindow类(未经测试):
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = Dispatcher.Invoke(
(Func<GeometryModel3D>)(() => new GeometryModel3D()));
}
WPF - I'm using BackgroundWorker to create a Model3D object, but when I want to add it to a Model3DGroup that is defined in the XAML, I get exception:
This is the whole code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
GeometryModel3D geometryModel3D = (GeometryModel3D)e.Result;
model3DGroup.Children.Add(geometryModel3D);
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
GeometryModel3D geometryModel3D = new GeometryModel3D();
e.Result = geometryModel3D;
}
}
and this is the whole XAML:
<Grid>
<Viewport3D Margin="4,4,4,4" Grid.Row="0" Grid.Column="0">
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup x:Name="model3DGroup">
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
</Grid>
In your RunWorkerCompleted handler you're adding a GeometryModel3D instance to a Model3DGroup, which was obviously created in a thread other than the UI thread, since the BackgroundWorker.DoWork handler is executed in a separate thread.
In short, WPF does not allow this, as you might have noticed from the exception message. All UI elements, or to be more precise, all DispatcherObject-derived objects in your application must be created in the same thread.
Get an overview of the WPF Threading Model and also see the Remarks section in the BackgroundWorker documentation.
EDIT: you could however create new GeometryModel3D instances by synchronously invoking the Dispatcher of your MainWindow class (without having tested that):
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = Dispatcher.Invoke(
(Func<GeometryModel3D>)(() => new GeometryModel3D()));
}
这篇关于无法使用与其父级Freezable属于不同线程的DependencyObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!