Compartilhar via


BindingOperations.EnableCollectionSynchronization Método

Definição

Permite que um objeto CollectionView participe do acesso sincronizado a uma coleção usada em vários threads.

Sobrecargas

EnableCollectionSynchronization(IEnumerable, Object)

Permite que um objeto CollectionView participe do acesso sincronizado a uma coleção usada em vários threads usando um mecanismo de bloqueio simples.

EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback)

Permite que um objeto CollectionView participe do acesso sincronizado a uma coleção usada em vários threads usando um mecanismo diferente de um bloqueio simples.

Comentários

Um aplicativo WPF pode exibir uma coleção de dados usando uma ItemsControl ou uma de suas subclasses (ListBox, DataGrid, TreeView, ListViewetc.). O WPF canaliza todo o seu acesso à coleção por meio de uma subclasse de CollectionView. Tanto o ItemsControl quanto o CollectionView têm afinidade com o thread no qual o foi criado, o ItemsControl que significa que usá-los em um thread diferente é proibido e gera uma exceção. Na verdade, essa restrição também se aplica à coleção.

Talvez você queira usar a coleção em vários threads.   Por exemplo, você deseja atualizar a coleção (adicionar ou remover itens) em um thread de "coleta de dados", enquanto exibe os resultados em um thread de "interface do usuário", para que a interface do usuário permaneça responsiva enquanto a coleta de dados está acontecendo. Nessa situação, você é responsável por garantir o acesso sincronizado ("thread-safe") à coleção.   Normalmente, isso é feito usando um mecanismo de bloqueio simples ou um mecanismo de sincronização mais elaborado, como semáforos, eventos de redefinição etc.

Embora seja necessário sincronizar o acesso do aplicativo à coleção, você também deve garantir que o acesso do WPF (especificamente de CollectionView) participe do mesmo mecanismo de sincronização.  Você pode fazer ao chamar o método EnableCollectionSynchronization.

Para usar uma coleção em vários threads, um deles é o thread de interface do usuário que possui o ItemsControl, um aplicativo tem as seguintes responsabilidades:

  1. Escolha um mecanismo de sincronização.

  2. Sincronize todo o acesso do aplicativo à coleção usando esse mecanismo.

  3. Chame EnableCollectionSynchronization para informar o WPF sobre o mecanismo.

  4. Verifique se uma alteração na coleção e a notificação dessa alteração (por meio INotifyCollectionChangedde ) são atômicas; nenhum acesso de outros threads pode intervir.  (Isso geralmente é gratuito. Por exemplo, ObservableCollection<T> garante isso, desde que todas as alterações sejam protegidas pela sincronização.)

  5. Se você chamar DisableCollectionSynchronization, essa chamada também deverá ocorrer no thread da interface do usuário.

  6. Se você quiser usar a mesma coleção em vários threads de interface do usuário, deverá chamar EnableCollectionSynchronization (e DisableCollectionSynchronization, se necessário) separadamente em cada thread de interface do usuário.

  7. Evite deadlock.  Isso já é responsabilidade do aplicativo depois que ele opta por usar a sincronização, mas também deve levar em conta a participação do WPF na sincronização, conforme discutido no parágrafo a seguir.

Em troca, o WPF fornece o seguinte comportamento:

  • O CollectionView acessa a coleção usando o mecanismo de sincronização especificado.

  • O CollectionView mantém uma "cópia de sombra" da coleção para uso no thread da interface do usuário.

  • CollectionChanged os eventos são enfileirados quando chegam (em qualquer thread).

  • Os eventos pendentes são aplicados à cópia de sombra de forma assíncrona no thread da interface do usuário quando ele tem a oportunidade de fazê-lo.

  • O CollectionView não usará diretamente nenhum outro mecanismo de sincronização visível para o aplicativo. Essa é a maneira do WPF ajudar a evitar deadlock (consulte o item anterior 7).  

O efeito líquido é que você pode alterar a coleção em qualquer thread e essas alterações eventualmente aparecem no ItemsControl quando o thread da interface do usuário tem tempo para "atualizar".  A implementação foi ajustada para limitar a taxa que altera o fluxo para o thread da interface do usuário para impedir que os threads em segundo plano saturam o thread da interface do usuário e a resposta à entrada normal do usuário.

EnableCollectionSynchronization(IEnumerable, Object)

Permite que um objeto CollectionView participe do acesso sincronizado a uma coleção usada em vários threads usando um mecanismo de bloqueio simples.

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)

Parâmetros

collection
IEnumerable

A coleção que precisa de acesso sincronizado.

lockObject
Object

O objeto a ser bloqueado ao acessar a coleção.

Comentários

Um aplicativo WPF pode exibir uma coleção de dados usando uma ItemsControl ou uma de suas subclasses (ListBox, DataGrid, TreeView, ListViewetc.). O WPF canaliza todo o seu acesso à coleção por meio de uma subclasse de CollectionView. Tanto o ItemsControl quanto o CollectionView têm afinidade com o thread no qual o foi criado, o ItemsControl que significa que usá-los em um thread diferente é proibido e gera uma exceção. Na verdade, essa restrição também se aplica à coleção.

Talvez você queira usar a coleção em vários threads.   Por exemplo, você deseja atualizar a coleção (adicionar ou remover itens) em um thread de "coleta de dados", enquanto exibe os resultados em um thread de "interface do usuário", para que a interface do usuário permaneça responsiva enquanto a coleta de dados está acontecendo. Nessa situação, você é responsável por garantir o acesso sincronizado ("thread-safe") à coleção e por garantir que o acesso do WPF (especificamente de CollectionView) participe do mesmo mecanismo de sincronização. Ao chamar o EnableCollectionSynchronization(IEnumerable, Object) método , você pode fazer isso usando um mecanismo de bloqueio simples.

Para usar uma coleção em vários threads, um dos quais é o thread de interface do usuário que possui o ItemsControl, você deve fazer o seguinte:

  1. Instancie um objeto a ser bloqueado ao acessar a coleção.

  2. Sincronize todo o acesso do aplicativo à coleção bloqueando esse objeto.

  3. Chame EnableCollectionSynchronization(IEnumerable, Object) para informar ao WPF que você está usando um mecanismo de bloqueio simples.

    • A chamada deve ocorrer no thread da interface do usuário.

    • A chamada deve ocorrer antes de usar a coleção em um thread diferente ou antes de anexar a coleção ao , o ItemsControlque for posterior.

  4. Verifique se uma alteração na coleção e a notificação dessa alteração (por meio INotifyCollectionChangedde ) são atômicas; nenhum acesso de outros threads pode intervir.  (Isso geralmente é gratuito. Por exemplo, ObservableCollection<T> garante isso, desde que todas as alterações sejam protegidas pela sincronização.)

  5. Se você chamar DisableCollectionSynchronization, essa chamada também deverá ocorrer no thread da interface do usuário.

  6. Se você quiser usar a mesma coleção em vários threads de interface do usuário, deverá chamar EnableCollectionSynchronization (e DisableCollectionSynchronization, se necessário) separadamente em cada thread de interface do usuário.

  7. Evite deadlock.  Isso já é responsabilidade do aplicativo depois que ele opta por usar a sincronização, mas também deve levar em conta a participação do WPF na sincronização. (Veja mais, abaixo.)

Em troca, o WPF fornece o seguinte comportamento:

  • O CollectionView acessa a coleção usando o mecanismo de bloqueio.

  • O CollectionView mantém uma "cópia de sombra" da coleção para uso no thread da interface do usuário.

  • CollectionChanged os eventos são enfileirados à medida que chegam (em qualquer thread).

  • Os eventos pendentes são aplicados à cópia de sombra de forma assíncrona no thread da interface do usuário quando ele tem a oportunidade de fazer isso.

  • O CollectionView não usará diretamente nenhum outro mecanismo de sincronização visível para o aplicativo. Essa é a maneira do WPF ajudar a evitar deadlock (consulte o item anterior 7).  

O efeito líquido é que você pode alterar a coleção em qualquer thread, e essas alterações eventualmente aparecem no ItemsControl quando o thread da interface do usuário tem tempo para "atualizar".  A implementação foi ajustada para limitar a taxa que altera o fluxo para o thread da interface do usuário para impedir que os threads em segundo plano saturam o thread da interface do usuário e esfomeem a resposta à entrada normal do usuário.

Aplica-se a

EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback)

Permite que um objeto CollectionView participe do acesso sincronizado a uma coleção usada em vários threads usando um mecanismo diferente de um bloqueio simples.

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)

Parâmetros

collection
IEnumerable

A coleção que precisa de acesso sincronizado.

context
Object

Um objeto passado para o retorno de chamada.

synchronizationCallback
CollectionSynchronizationCallback

O retorno de chamada invocado sempre que for necessário acessar a coleção. É possível usá-lo para garantir que a coleção seja acessada por um thread por vez.

Comentários

Um aplicativo WPF pode exibir uma coleção de dados usando uma ItemsControl ou uma de suas subclasses (ListBox, DataGrid, TreeView, ListViewetc.). O WPF canaliza todo o seu acesso à coleção por meio de uma subclasse de CollectionView. Tanto o ItemsControl quanto o CollectionView têm afinidade com o thread no qual o foi criado, o ItemsControl que significa que usá-los em um thread diferente é proibido e gera uma exceção. Na verdade, essa restrição também se aplica à coleção.

Talvez você queira usar a coleção em vários threads.   Por exemplo, você deseja atualizar a coleção (adicionar ou remover itens) em um thread de "coleta de dados", enquanto exibe os resultados em um thread de "interface do usuário", para que a interface do usuário permaneça responsiva enquanto a coleta de dados está acontecendo. Nessa situação, você é responsável por garantir o acesso sincronizado ("thread-safe") à coleção e por garantir que o acesso do WPF (especificamente de CollectionView) participe do mesmo mecanismo de sincronização. Ao chamar o EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) método , você pode fazer isso usando um mecanismo de sincronização, como semáforos, um evento de redefinição etc.

Para usar uma coleção em vários threads, um dos quais é o thread de interface do usuário que possui o ItemsControl, você deve fazer o seguinte:

  1. Escolha um mecanismo de sincronização.

  2. Sincronize todo o acesso do aplicativo à coleção usando esse mecanismo.

  3. Chame a EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) sobrecarga para informar ao WPF que você está usando um mecanismo diferente do bloqueio simples.

    • A chamada deve ocorrer no thread da interface do usuário.

    • A chamada deve ocorrer antes de usar a coleção em um thread diferente ou antes de anexar a coleção ao , o ItemsControlque for posterior.

  4. Verifique se uma alteração na coleção e a notificação dessa alteração (por meio INotifyCollectionChangedde ) são atômicas; nenhum acesso de outros threads pode intervir.  (Isso geralmente é gratuito. Por exemplo, ObservableCollection<T> garante isso, desde que todas as alterações sejam protegidas pela sincronização.)

  5. Se você chamar DisableCollectionSynchronization, essa chamada também deverá ocorrer no thread da interface do usuário.

  6. Se você quiser usar a mesma coleção em vários threads de interface do usuário, deverá chamar EnableCollectionSynchronization (e DisableCollectionSynchronization, se necessário) separadamente em cada thread de interface do usuário.

  7. Evite deadlock.  Isso já é responsabilidade do aplicativo depois que ele opta por usar a sincronização, mas também deve levar em conta a participação do WPF na sincronização. (Veja mais, abaixo.)

Em troca, o WPF fornece o seguinte comportamento:

  • O CollectionView acessa a coleção chamando o registrado CollectionSynchronizationCallback com os seguintes argumentos:

    • collection: a coleção de interesse.
    • context: o objeto de contexto registrado.
    • accessMethod: um delegado que executa o acesso real.
    • writeAccess: true se o delegado modificar a coleção; false caso contrário, .

    O CollectionSynchronizationCallback deve estabelecer a sincronização na coleção (usando o context objeto e o writeAccess valor, conforme apropriado), chamar o accessMethode liberar a sincronização.

  • O CollectionView mantém uma "cópia de sombra" da coleção para uso no thread da interface do usuário.

  • CollectionChanged os eventos são enfileirados à medida que chegam (em qualquer thread).

  • Os eventos pendentes são aplicados à cópia de sombra de forma assíncrona no thread da interface do usuário quando ele tem a oportunidade de fazer isso.

  • O CollectionView não usará diretamente nenhum outro mecanismo de sincronização visível para o aplicativo. Essa é a maneira do WPF ajudar a evitar deadlock (consulte o item anterior 7).  

O efeito líquido é que você pode alterar a coleção em qualquer thread, e essas alterações eventualmente aparecem no ItemsControl quando o thread da interface do usuário tem tempo para "atualizar".  A implementação foi ajustada para limitar a taxa que altera o fluxo para o thread da interface do usuário para impedir que os threads em segundo plano saturam o thread da interface do usuário e esfomeem a resposta à entrada normal do usuário.

O context parâmetro é um objeto arbitrário que é passado para o callback. Você pode usá-lo para determinar o mecanismo de sincronização usado para controlar o acesso ao collection. Context pode ser null.

Aplica-se a