【发布时间】:2011-08-04 16:25:54
【问题描述】:
我在 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>
您好, 多米尼克
【问题讨论】:
-
如果你能展示你的一些代码会有所帮助。
-
我通过编辑操作在问题中添加了一些代码 sn-ps。
-
您不应将
[Solved]添加到您的标题或在您的问题中发布解决方案。您将不得不等待 24 小时,但您应该在自己的答案中发布解决方案,然后您可以接受(延迟后再次)。然后这会向系统和其他用户表明问题已解决。 -
@ChrisF - 对不起 [已解决] 标签。我只是想阻止其他人为已经解决的问题付出努力。我尝试解决了大约两天,并在我发布问题后找到了解决方案。
-
别太担心 - 关于在您发布后立即解决,这似乎经常发生!
标签: c# wpf exception binding multithreading