Je prévois de partager une liste entre plusieurs threads. La liste sera verrouillée lors d'une modification, qui arrive rarement. Existe-t-il un problème de sécurité de thread si plusieurs itérations sont fabriquées à partir de threads différents via la liste simultanément? P>
5 Réponses :
Si vous le pouvez (si vous pouvez utiliser .NET 4 c'est), utilisez blocageCollection
: p>
fournit des capacités de blocage et de liaison pour les collections de fil-sécurité qui implémentent
iproducerconsumercollection
code>. p> blockQuote> Sinon, sinon encapsule complètement la liste et ajoutez des méthodes de fil-sécurité qui accèdent à la liste
Liste
's code>. Ne faites pas référence à la liste publique ou renvoyez-la à partir de toutes méthodes - encapsulez toujours la référence afin que vous puissiez garantir que vous vous classez autour de tout accès. P>
Y a-t-il un coût pour utiliser BlockingCollection
@Behroz: Plus de coûts qu'un wrapper personnalisé autour de la liste
liste
Je suis surpris que cette réponse soit acceptée. Le comportement par défaut de blocageCollection code> est une file d'attente plutôt qu'une liste. Il n'y a aucun moyen d'y accéder par index et il n'y a aucun moyen de le faire itérer sans éliminer les articles. Je suppose que l'OP avait vraiment besoin d'une file d'attente.
Queue d'identification par défaut, mais vous pouvez le remplacer par tout ce que vous voulez.
a Liste
N'est-ce pas une classe de fil-sécurité, mais si vous vous verrouillez chaque fois que vous lisez / écrivez-y, il n'y aura pas de problèmes. Selon la documentation: P>
Statique publique (partagée dans Visual Basic) Les membres de ce type sont le fil sûr. N'importe quel cas ne sont pas Garanti d'être le fil sûr. P>
A
Liste
code> peut prendre en charge plusieurs lecteurs simultanément, aussi longtemps que la la collecte n'est pas modifiée. Énumérer à travers une collection est intrinsèquement pas un coffre-fort procédure. Dans le cas rare où un L'énumération soutient avec un ou plusieurs accès écrit, le seul moyen de s'assurer La sécurité du fil est de verrouiller la Collection pendant toute la énumération. Permettre la collection à accéder par plusieurs threads pour lecture et écriture, vous devez Mettre en œuvre votre propre synchronisation. P> blockQuote>
Il peut être lire em> à partir de plusieurs threads simultanément, si c'est ce que vous demandez. Considérons une serrure auteur de lecteur si oui. P>
Liste
System.Threading.readerwriterlock Code> (qui permet plusieurs lecteurs mais un seul écrivain). P>
Il n'ya presque jamais de cas pour préférer ReaderWriterLock code> sur
ReaderWriterLockSlim code>. La version
SLIM code> fonctionne mieux et a une API bien meilleure.
TRUE, mais ReaderWriterLocksLim code> est uniquement disponible en v3.5 + comme dans
System.core.dll code>.
ReaderWriterLock CODE> est disponible auprès de V1.1 + et se trouve dans le
MSCORLIB code>. Malheureusement, je suis obligé de travailler avec beaucoup de code .net 2.0, donc je n'ai donc aucun choix dans la matière.
Pour répondre à cette question, vous devez d'abord jeter un coup d'œil à la documentation, puis sur le code source et il y a un avertissement Darin Dimitrov EM> a cité la documentation de l'année 2010 et il y a des différences pour l'année 2021: P>
Les membres publiques statiques (partagés dans Visual Basic) de ce type sont du thread
en sécurité. Tous les membres de l'instance ne sont pas garantis pour être en sécurité. P>
Il est prudent d'effectuer plusieurs opérations de lecture sur une liste, mais
Les problèmes peuvent se produire si la collection est modifiée alors qu'elle est en cours de lecture.
Pour assurer la sécurité du fil, verrouillez la collection pendant une lecture ou une écriture
opération. Pour permettre une collection d'être accessible par plusieurs threads
Pour la lecture et l'écriture, vous devez mettre en œuvre votre propre synchronisation.
Pour les collections avec synchronisation intégrée, voir les classes de la
System.Collections. Espace de nomsCurrent. Pour un coffre-fort intrinsèquement
Alternative, voir la classe d'immutablelist. P>
blockQuote>
Comme vous pouvez le constater, il n'y a déjà pas une telle phrase p>
énumérer à travers une collection n'est intrinsèquement pas un coffre-fort
Procédure p>
blockQuote>
Donc, un conseil est - vérifier le documentation et Mise en œuvre de La réponse à votre question est - cela dépend fort>. p>
Si vous utilisez si la liste ne sera pas modifiée du tout pendant l'itération forte>, alors l'itération est le fil sûr. P> liste
Liste
foreach code> à itérer via la liste, si la liste a été modifiée, même appelez simplement la liste
[i] = valeur code>, dans laquelle la valeur
code> est égal à la liste
[i] code>, vous deviendrez une exception, car la liste
pour code> La boucle de cet endroit ne jettera pas une exception, si vous modifiez une valeur dans la liste, mais la modification de la longueur de la liste peut être dangereuse. P>
Je crois que la raison pour laquelle ils ont supprimé le "énumérer à travers une collection ne sont intrinsèquement pas une procédure de fil-sécurité" i> la déclaration est parce qu'elle est réfutée par la simple existence des collections immuables. Rien n'a effectivement changé avec la liste
@Theodorzoulias Recherche dans la mise en œuvre de BinarinCompatibilittibilité.TaretsatLeast_desktop_v4_5 Code>
Ceci suggère que la méthode foreach code> était incompatible avec la norme
envahir code> énumération avant .NET 4.5, et ils l'ont réparé en rendant le
foreach code> se comporter exactement comme le
foreach code>. Le
foreach code> est resté le même. BTW Il est assez facile d'énumérer une liste
foreach (Var Article en énumérable.Range (0 , list.compt) .Sélectionnez (i => liste [i])) {... code>. Mais cela ne rend pas le fil de recensement. Cela ne fait que la version-agnostique.
Je voulais juste dire qu'il y avait des changements et qu'ils peuvent survenir à l'avenir, donc un conseil pour inspecter la mise en œuvre.
Rekshino Inspection Le code source peut certainement fournir des informations sur les intentions des développeurs. Mais prévoir les changements pouvant survenir à l'avenir est un étirement. Mon avis est que nous ne devrions pas nous attendre à des modifications majeures de la fonctionnalité principale et des caractéristiques d'un composant aussi populaire, comme la liste
Si la liste est verrouillée correctement, quelle sorte de problème pourrait-il être?
Vous ne pouvez pas verrouiller une liste, vous pouvez uniquement bloquer le code. Demandez à tous les codes qui accède à la liste (ou à ses objets d'élément) entrez une instruction de verrouillage utilisant un objet privé pour garder l'état de verrouillage.