35 votes

Pourquoi n'y a-t-il pas de file d'attente synchronisée générique dans .NET?

J'ai remarqué que vous pouvez appeler Queue.Synchronize pour obtenir un objet de file d'attente thread-safe, mais la même méthode n'est pas disponible sur Queue <T>. Quelqu'un sait-il pourquoi? Cela semble un peu bizarre.

53voto

Matt Ryan Points 833

Mise à jour - dans .NET 4, il est maintenant de ConcurrentQueue<T> dans le Système.Les Collections.Simultanées, comme indiqué ici http://msdn.microsoft.com/en-us/library/dd267265.aspx. Il est intéressant de noter que son IsSynchronized méthode (à juste titre) renvoie la valeur false.

ConcurrentQueue<T> est un terrain de réécriture, de la création de copies de la file d'attente à énumérer et à l'aide de advanced non-verrouillage des techniques comme l' Interlocked.CompareExchange() et Thread.SpinWait().

Le reste de cette réponse est encore pertinent dans la mesure où il se rapporte à la disparition de l'ancien Synchronize() et SyncRoot membres, et pourquoi ils ne fonctionnent pas très bien à partir d'un point de vue API.


Comme par Zooba du commentaire, la BCL équipe a décidé que de trop nombreux développeurs ont été un malentendu le but de Synchroniser (et dans une moindre mesure, SyncRoot)

Brian Grunkemeyer décrit ce sur la BCL blog de l'équipe d'un couple d'années en arrière: http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx

La question clé est d'obtenir la bonne granularité autour de serrures, où certains développeurs auraient la naïveté de l'utilisation de plusieurs propriétés ou des méthodes sur un "synchronisé" de collecte et de croire que leur code soit thread-safe. Brian utilise File d'attente comme à son exemple,

if (queue.Count > 0) {
    object obj = null;
    try {
        obj = queue.Dequeue();

Les développeurs ne se rendent pas compte que le Comte pouvait être changé par un autre thread avant de la file d'attente a été invoquée.

Forcer les développeurs à l'utilisation explicite de l'instruction lock autour de l'ensemble de l'opération d'éviter ce faux sentiment de sécurité.

Comme Brian mentionne, la suppression de SyncRoot a été en partie parce qu'il a été principalement mis en place pour appuyer Synchronisés, mais aussi parce que dans de nombreux cas, il y a un meilleur choix de la serrure de l'objet la plupart du temps, la File d'attente de l'instance elle-même, ou un

private static object lockObjForQueueOperations = new object();

sur la classe possédant l'exemple de la File d'attente...

Cette dernière approche est généralement plus sûre car elle permet d'éviter certaines autres communes de pièges:

Comme ils le disent, le filetage est dur, et ce qui semble simple peut être dangereux.

7voto

Domenic Points 40761

Vous pouvez trouver le CTP parallèle à vérifier; voici une entrée de blog des gars qui le mettent ensemble qui est assez d'actualité:

Énumération des collections simultanées

Ce n'est pas tout à fait la même chose, mais cela pourrait résoudre votre plus gros problème. (Ils utilisent même Queue<T> contre ConcurrentQueue<T> comme exemple.)

6voto

Shane Castle Points 1252

Il y en a un maintenant, en .Net 4.0:

 ConcurrentQueue<T> 
 

dans System.Collections.Concurrent

http://msdn.microsoft.com/en-us/library/dd267265.aspx

0voto

Zooba Points 6440

(Je suppose que vous voulez dire Queue<T> pour le second.)

Je ne peux pas vraiment répondre à la question, sauf que le IsSynchronized et SyncRoot propriétés (mais pas Synchroniser() explicitement) sont héritées de l'interface ICollection. Aucun des génériques des collections de l'utiliser et le ICollection<T> interface ne comprend pas SyncRoot.

Pourquoi il n'est pas inclus, je ne peux que spéculer qu'ils n'étaient pas utilisés, soit dans le sens voulu par les concepteurs de la bibliothèque ou tout simplement ils n'ont pas été suffisamment utilisés pour justifier leur maintien dans les collections récentes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X