J'ai suivi this tutorial pour créer une file d'attente prioritaire et l'a enveloppée avec une collection de blocage. J'ai un DataGrid que j'ai câblé à la file d'attente prioritaire sous-jacente qui émet des événements de changement. Je peux ajouter des éléments à la collection à partir du thread de l'interface utilisateur sans aucun problème, et il bloque lorsque le tampon est plein comme il est censé le faire.BlockingCollection + thread UI
Maintenant, comment consommer les articles? Voici ce que j'ai:
public DownloadViewModel()
{
Queue = new ConcurrentPriorityQueue<DownloadItem>(10);
Buffer = new BlockingCollection<KeyValuePair<int, DownloadItem>>(Queue, 10000);
Task.Factory.StartNew(() =>
{
KeyValuePair<int, DownloadItem> item;
while(!Buffer.IsCompleted)
{
if(Buffer.TryTake(out item))
{
// do something with the item
}
Thread.SpinWait(100000);
}
});
}
Mais dès que j'ajouté que Task.Factory.StartNew
peu, mon application prend soudainement 30 secondes avant que la fenêtre apparaît (avant qu'il ne soit instant), et quand je fais ajouter un article que je reçois l'exception
Ce type de CollectionView ne prend pas en charge les modifications apportées à sa SourceCollection à partir d'un thread différent du thread Dispatcher.
Ce que je comprends, mais est-il vraiment nécessaire de prendre les éléments en utilisant le fil de l'interface utilisateur? Cela ne va-t-il pas à l'encontre de l'objectif de BlockingCollection? Je veux créer 4 ou 8 consommateurs et les faire fonctionner en parallèle.
Comment cela est-il censé être fait?
Il est vraiment nécessaire de mettre à jour uniquement un contrôle d'interface utilisateur à partir du thread d'interface utilisateur. C'est ce que l'exception vous dit. Oui, cela détruit rapidement l'utilité des schémas de threads élaborés. –
@Hans: Bien sûr, mais lorsque la file d'attente de blocage tente de prendre un élément, la file d'attente sous-jacente émet une notification de changement, .. pourquoi cela ne peut-il pas être automatiquement renvoyé au thread d'interface utilisateur? Pourquoi les consommateurs devraient-ils être retenus? Peu importe ... Je suis prêt à accepter n'importe quel sol'n dès maintenant, même si c'est un peu moins efficace que ce que je pense qu'il devrait être. J'imagine que c'est un paradigme assez commun .. producteur-consommateur n'est rien de nouveau, il ne devrait pas être si difficile d'afficher les éléments restants à l'utilisateur? – mpen
Rien n'est jamais automatique ou facile quand il s'agit de filetage. Collectez les résultats dans une liste et utilisez Dispatcher.BeginInvoke pour mettre à jour l'interface utilisateur. –