У меня проблема с межпоточными операциями в C # / WPF / .NET 4.0.
Ситуация:
Мне нужно создать дерево объектовкогда пользователь нажимает кнопку, а затем привязывается к дереву.Поскольку создание занимает много времени (дочерние объекты создаются рекурсивно), я использовал Thread / BackgroundWorker / Task для предотвращения зависания пользовательского интерфейса.
Проблема:
Я получаю исключение XamlParserException (необходимо создать DependencySource в том же потоке, что и объект DependencyObject) при привязке к дереву объектов.
Я понимаю проблему, но как ее можно исправить?Я не могу создать дерево объектов в потоке пользовательского интерфейса, потому что это замораживает пользовательский интерфейс.Но я также не могу создать дерево объектов в другом потоке, потому что тогда я не могу привязаться к нему.
Есть ли способ «маршалировать» объекты в потоке пользовательского интерфейса?
Код обработчика событий (выполняется в потоке пользовательского интерфейса)
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>
Привет, Доминик