Поделиться через


BindingOperations.EnableCollectionSynchronization Метод

Определение

Позволяет объекту CollectionView участвовать в синхронизированном доступе к коллекции, используемой в нескольких потоках.

Перегрузки

EnableCollectionSynchronization(IEnumerable, Object)

Позволяет объекту CollectionView участвовать в синхронизированном доступе к коллекции, используемой в нескольких потоках, с помощью простого механизма блокировки.

EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback)

Позволяет объекту CollectionView участвовать в синхронизированном доступе к коллекции, используемой в нескольких потоках, с помощью механизма, отличного от простой блокировки.

Комментарии

Приложение WPF может отображать коллекцию данных с помощью ItemsControl или одного из его подклассов (ListBox, , DataGridTreeView, ListViewи т. д.). WPF направляет весь доступ к коллекции через подкласс CollectionView. И , ItemsControl и CollectionView имеют сходство с потоком ItemsControl , в котором был создан , что означает, что их использование в другом потоке запрещено и вызывает исключение. Фактически это ограничение применяется и к коллекции.

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

Хотя необходимо синхронизировать доступ приложения к коллекции, необходимо также гарантировать, что доступ из WPF (в частности, из CollectionView) участвует в том же механизме синхронизации.  Это можно сделать, вызвав метод EnableCollectionSynchronization.

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

  1. Выберите механизм синхронизации.

  2. Синхронизируйте весь доступ из приложения к коллекции с помощью этого механизма.

  3. Вызовите EnableCollectionSynchronization , чтобы сообщить WPF о механизме.

    • Вызов должен выполняться в потоке пользовательского интерфейса.

    • Вызов должен выполняться перед использованием коллекции в другом потоке или перед присоединением коллекции к ItemsControl, в зависимости от того, что произойдет позже.

    • Вызов перегрузки при EnableCollectionSynchronization(IEnumerable, Object) использовании простого механизма блокировки; вызов перегрузки при EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) использовании более сложного механизма.

  4. Убедитесь, что изменение коллекции и уведомление об этом изменении (через INotifyCollectionChanged) являются атомарными; доступ из других потоков не может вмешаться.  (Обычно это бесплатно. Например, ObservableCollection<T> гарантирует это при условии, что все изменения защищены синхронизацией.)

  5. При вызове DisableCollectionSynchronizationэтот вызов также должен выполняться в потоке пользовательского интерфейса.

  6. Если вы хотите использовать одну и ту же коллекцию в нескольких потоках пользовательского интерфейса, необходимо вызвать EnableCollectionSynchronizationDisableCollectionSynchronization, если необходимо) отдельно в каждом потоке пользовательского интерфейса.

  7. Избегайте взаимоблокировки.  Это уже ответственность приложения после того, как оно решит использовать синхронизацию, но оно также должно учитывать участие WPF в синхронизации, как описано в следующем абзаце.

В свою очередь, WPF обеспечивает следующее поведение:

  • объект CollectionView обращается к коллекции с помощью заданного механизма синхронизации.

  • сохраняет CollectionView "теневое копирование" коллекции для использования в потоке пользовательского интерфейса.

  • CollectionChanged События помещаются в очередь по мере их поступления (в любом потоке).

  • Ожидающие события применяются к теневой копии асинхронно в потоке пользовательского интерфейса, когда у него есть возможность сделать это.

  • Не CollectionView будет напрямую использовать любой другой механизм синхронизации, видимый приложению. Это способ WPF, помогающий избежать взаимоблокировки (см. предыдущий пункт 7).  

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

EnableCollectionSynchronization(IEnumerable, Object)

Позволяет объекту CollectionView участвовать в синхронизированном доступе к коллекции, используемой в нескольких потоках, с помощью простого механизма блокировки.

public:
 static void EnableCollectionSynchronization(System::Collections::IEnumerable ^ collection, System::Object ^ lockObject);
public static void EnableCollectionSynchronization (System.Collections.IEnumerable collection, object lockObject);
static member EnableCollectionSynchronization : System.Collections.IEnumerable * obj -> unit
Public Shared Sub EnableCollectionSynchronization (collection As IEnumerable, lockObject As Object)

Параметры

collection
IEnumerable

Коллекция, которой требуется синхронизированный доступ.

lockObject
Object

Объект, который будет блокироваться при доступе к коллекции.

Комментарии

Приложение WPF может отображать коллекцию данных с помощью ItemsControl или одного из его подклассов (ListBox, , DataGridTreeView, ListViewи т. д.). WPF направляет весь доступ к коллекции через подкласс CollectionView. И , ItemsControl и CollectionView имеют сходство с потоком ItemsControl , в котором был создан , что означает, что их использование в другом потоке запрещено и вызывает исключение. Фактически это ограничение применяется и к коллекции.

Может потребоваться использовать коллекцию в нескольких потоках.   Например, вы хотите обновить коллекцию (добавить или удалить элементы) в потоке сбора данных, отображая результаты в потоке пользовательского интерфейса, чтобы пользовательский интерфейс оставался адаптивным во время сбора данных. В такой ситуации вы несете ответственность за обеспечение синхронизированного ("потокобезопасного") доступа к коллекции и за обеспечение того, чтобы доступ из WPF (в частности, из CollectionView) участвовал в одном механизме синхронизации. Вызов метода EnableCollectionSynchronization(IEnumerable, Object) позволяет сделать это с помощью простого механизма блокировки.

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

  1. Создание экземпляра объекта для блокировки при доступе к коллекции.

  2. Синхронизируйте весь доступ из приложения к коллекции, блокируя этот объект.

  3. Вызовите EnableCollectionSynchronization(IEnumerable, Object) , чтобы сообщить WPF, что используется простой механизм блокировки.

    • Вызов должен выполняться в потоке пользовательского интерфейса.

    • Вызов должен выполняться перед использованием коллекции в другом потоке или перед присоединением коллекции к ItemsControl, в зависимости от того, что произойдет позже.

  4. Убедитесь, что изменение коллекции и уведомление об этом изменении (через INotifyCollectionChanged) являются атомарными; доступ из других потоков не может вмешаться.  (Обычно это бесплатно. Например, ObservableCollection<T> гарантирует это при условии, что все изменения защищены синхронизацией.)

  5. При вызове DisableCollectionSynchronizationэтот вызов также должен выполняться в потоке пользовательского интерфейса.

  6. Если вы хотите использовать одну и ту же коллекцию в нескольких потоках пользовательского интерфейса, необходимо вызвать EnableCollectionSynchronizationDisableCollectionSynchronization, если необходимо) отдельно в каждом потоке пользовательского интерфейса.

  7. Избегайте взаимоблокировки.  Это уже ответственность приложения после того, как оно решит использовать синхронизацию, но оно также должно учитывать участие WPF в синхронизации. (Дополнительные сведения см. ниже.)

В свою очередь, WPF обеспечивает следующее поведение:

  • Объект CollectionView обращается к коллекции с помощью механизма блокировки.

  • сохраняет CollectionView "теневое копирование" коллекции для использования в потоке пользовательского интерфейса.

  • CollectionChanged События помещаются в очередь по мере их поступления (в любом потоке).

  • Ожидающие события применяются к теневой копии асинхронно в потоке пользовательского интерфейса, когда у него есть возможность сделать это.

  • не CollectionView будет напрямую использовать любой другой механизм синхронизации, видимый приложению. Это способ WPF, помогающий избежать взаимоблокировки (см. предыдущий пункт 7).  

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

Применяется к

EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback)

Позволяет объекту CollectionView участвовать в синхронизированном доступе к коллекции, используемой в нескольких потоках, с помощью механизма, отличного от простой блокировки.

public:
 static void EnableCollectionSynchronization(System::Collections::IEnumerable ^ collection, System::Object ^ context, System::Windows::Data::CollectionSynchronizationCallback ^ synchronizationCallback);
public static void EnableCollectionSynchronization (System.Collections.IEnumerable collection, object context, System.Windows.Data.CollectionSynchronizationCallback synchronizationCallback);
static member EnableCollectionSynchronization : System.Collections.IEnumerable * obj * System.Windows.Data.CollectionSynchronizationCallback -> unit
Public Shared Sub EnableCollectionSynchronization (collection As IEnumerable, context As Object, synchronizationCallback As CollectionSynchronizationCallback)

Параметры

collection
IEnumerable

Коллекция, которой требуется синхронизированный доступ.

context
Object

Объект, который передается в функцию обратного вызова.

synchronizationCallback
CollectionSynchronizationCallback

Функция обратного вызова, которая вызывается каждый раз, когда запрашивается доступ к коллекции. С его помощью можно проверить, осуществляет ли доступ к коллекции одновременно только один поток.

Комментарии

Приложение WPF может отображать коллекцию данных с помощью ItemsControl или одного из его подклассов (ListBox, , DataGridTreeView, ListViewи т. д.). WPF направляет весь доступ к коллекции через подкласс CollectionView. И , ItemsControl и CollectionView имеют сходство с потоком ItemsControl , в котором был создан , что означает, что их использование в другом потоке запрещено и вызывает исключение. Фактически это ограничение применяется и к коллекции.

Может потребоваться использовать коллекцию в нескольких потоках.   Например, вы хотите обновить коллекцию (добавить или удалить элементы) в потоке сбора данных, отображая результаты в потоке пользовательского интерфейса, чтобы пользовательский интерфейс оставался адаптивным во время сбора данных. В такой ситуации вы несете ответственность за обеспечение синхронизированного ("потокобезопасного") доступа к коллекции и за обеспечение того, чтобы доступ из WPF (в частности, из CollectionView) участвовал в одном механизме синхронизации. EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) Вызывая метод , это можно сделать с помощью механизма синхронизации, такого как семафоры, событие сброса и т. д.

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

  1. Выберите механизм синхронизации.

  2. Синхронизируйте весь доступ из приложения к коллекции с помощью этого механизма.

  3. Вызовите перегрузку, EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) чтобы сообщить WPF, что используется механизм, отличный от простой блокировки.

    • Вызов должен выполняться в потоке пользовательского интерфейса.

    • Вызов должен выполняться перед использованием коллекции в другом потоке или перед присоединением коллекции к ItemsControl, в зависимости от того, что произойдет позже.

  4. Убедитесь, что изменение коллекции и уведомление об этом изменении (через INotifyCollectionChanged) являются атомарными; доступ из других потоков не может вмешаться.  (Обычно это бесплатно. Например, ObservableCollection<T> гарантирует это при условии, что все изменения защищены синхронизацией.)

  5. При вызове DisableCollectionSynchronizationэтот вызов также должен выполняться в потоке пользовательского интерфейса.

  6. Если вы хотите использовать одну и ту же коллекцию в нескольких потоках пользовательского интерфейса, необходимо вызвать EnableCollectionSynchronizationDisableCollectionSynchronization, если необходимо) отдельно в каждом потоке пользовательского интерфейса.

  7. Избегайте взаимоблокировки.  Это уже ответственность приложения после того, как оно решит использовать синхронизацию, но оно также должно учитывать участие WPF в синхронизации. (Дополнительные сведения см. ниже.)

В свою очередь, WPF обеспечивает следующее поведение:

  • Объект CollectionView обращается к коллекции, вызывая зарегистрированный CollectionSynchronizationCallback с помощью следующих аргументов:

    • collection: интересующая коллекция.
    • context: зарегистрированный объект контекста.
    • accessMethod: делегат, выполняющий фактический доступ.
    • writeAccess: значение , true если делегат изменит коллекцию; false в противном случае — значение .

    Необходимо CollectionSynchronizationCallback установить синхронизацию коллекции (используя context объект и writeAccess значение, если это необходимо), вызвать , а затем освободить синхронизацию accessMethod.

  • сохраняет CollectionView "теневое копирование" коллекции для использования в потоке пользовательского интерфейса.

  • CollectionChanged События помещаются в очередь по мере их поступления (в любом потоке).

  • Ожидающие события применяются к теневой копии асинхронно в потоке пользовательского интерфейса, когда у него есть возможность сделать это.

  • не CollectionView будет напрямую использовать любой другой механизм синхронизации, видимый приложению. Это способ WPF, помогающий избежать взаимоблокировки (см. предыдущий пункт 7).  

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

Параметр context является произвольным объектом, который передается в callback. Его можно использовать для определения механизма синхронизации, используемого для управления доступом к collection. Context может иметь значение null.

Применяется к