我在C#/ WPF/.NET 4.0中遇到了跨线程操作问题。在工作线程中创建对象并绑定到它们
情况:
我当用户点击一个按钮来创建一个对象树,然后绑定到树。因为创建需要很长时间(子对象被递归实例化),所以我使用了Thread/BackgroundWorker/Task来防止UI冻结。
问题:
我得到一个XamlParserException(必须在同一个线程中的DependencyObject创建DependencySource)绑定到对象树时。
我明白这个问题,但怎么解决?我无法在UI线程上创建对象树,因为这会冻结UI。但是我也无法在另一个线程上创建对象树,因为那样我就无法绑定到它。
有没有办法'编组'对象到UI线程?
事件处理程序代码(上UI线程执行)
private void OnDiff(object sender, RoutedEventArgs e)
{
string path1 = this.Path1.Text;
string path2 = this.Path2.Text;
// Some simple UI updates.
this.ProgressWindow.SetText(string.Format(
"Comparing {0} with {1}...",
path1, path2));
this.IsEnabled = false;
this.ProgressWindow.Show();
this.ProgressWindow.Focus();
// The object tree to be created.
Comparison comparison = null;
Task.Factory.StartNew(() =>
{
// May take a few seconds...
comparison = new Comparison(path1, path2);
}).ContinueWith(x =>
{
// Again some simple UI updates.
this.ProgressWindow.SetText("Updating user interface...");
this.DiffView.Items.Clear();
this.Output.Items.Clear();
foreach (Comparison diffItem in comparison.Items)
{
this.DiffView.Items.Add(diffItem);
this.AddOutput(diffItem);
}
this.Output.Visibility = Visibility.Visible;
this.IsEnabled = true;
this.ProgressWindow.Hide();
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
实施例结合
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource DataGridIconCellTemplate}"/>
<DataGridTextColumn Header="Status" Binding="{Binding Path=ItemStatus}"/>
<DataGridTextColumn Header="Type" Binding="{Binding Path=ItemType}"/>
<DataGridTextColumn Header="Path" Binding="{Binding Path=RelativePath}"
Width="*"/>
</DataGrid.Columns>
问候, 多米尼克
这将有助于如果你能告诉你的一些代码。 – 2011-04-13 13:01:12
我通过编辑操作为问题添加了一些代码片段。 – Korexio 2011-04-13 13:30:47
你不应该在你的标题中加入'[Solved]'或者在你的问题中发布解决方案。您将不得不等待24小时,但您应该在自己的答案中发布解决方案,然后您可以接受(延迟后再次)。这然后向系统和其他用户指出问题已经解决。 – ChrisF 2011-04-13 13:57:12