Безопасна ли привязка WPF к параллельным коллекциям?

Мне было интересно, безопасно ли привязывать элемент управления WPF к параллельной коллекции, в частности, к классу-обертке вокруг одного из System.Collections.Concurrent коллекции, которые также реализует INotifyCollectionChanged?

Я это понимаю CollectionChanged должен вызываться в потоке пользовательского интерфейса (и без параметров индекса). Но что произойдет, если другой поток манипулирует исходной коллекцией во время обновления интерфейса? WPF просто изящно игнорирует проблему (как это происходит во многих других местах)?

1 ответ

Решение

Это зависит от реализации вашей обертки. Давайте сделаем простой пример добавления INotifyCollectionChanged к BlockingCollection<T> разрешить вызовы не-потоков UI:

public void AddNotified(T item)
{
    base.Add(item);

    var args = new NotifyCollectionChangedEventArgs(
        NotifyCollectionChangedAction.Add,
        item,
        Count - 1);

    //Ensure no items are changed until the UI is updated

    Application.Current.Dispatcher.Invoke(() =>
        CollectionChanged?.Invoke(this, args));
}

Реализация Add сам по себе является потокобезопасным, но чтобы убедиться, что пользовательский интерфейс отображает текущие элементы реализации, вам необходимо убедиться, что между добавлением и обновлением нет других элементов (см. комментарий в коде).

WPF обновляет пользовательский интерфейс на основе NotifyCollectionChangedAction и обновленные элементы переданы при поднятии INotifyCollectionChanged.CollectionChanged, Это означает, что пользовательский интерфейс полагается на эту информацию. Результат: временное обновление коллекции приводит к несинхронизированному интерфейсу пользователя до тех пор, пока обновление не будет запущено или NotifyCollectionChangedAction.Reset был вызван и пользовательский интерфейс показывает различные элементы, как внутри вашей исходной коллекции.

Синхронизация коллекций с пользовательским интерфейсом - очень широкая и интересная тема. Уже есть несколько доступных решений, которые могут соответствовать вашей конкретной проблеме. Чтобы дать вам несколько возможных подходов к решению подобных проблем, взгляните на следующие ссылки:

Другие вопросы по тегам