J'essaie d'incrémenter un élément dans une liste en C #, mais j'en ai besoin pour être en sécurité, le comte ne s'affiche pas.
Je sais que vous pouvez le faire pour des entiers: P> mais cela ne fonctionne pas sur une liste que j'ai ci-après jusqu'à présent: p> interlocked.incrènement (ref SDMPObjectList1Count); code> p>
lock (padlock)
{
DifferenceList[diff[d].PropertyName] = DifferenceList[diff[d].PropertyName] + 1;
}
3 Réponses :
Vérifiez la variable que vous avez verrouillée sur "Cadenock", normalement, vous pouvez la définir comme objet statique privé cadenas = nouvel objet () code>. Si vous ne le définissez pas comme statique, chaque objet a sa propre copie, il ne fonctionnera donc pas. P>
Cela dépend des données. Si les données ne sont pas statiques, il n'est pas nécessaire que l'objet de verrouillage soit statique; Vous seriez inutilement de synchroniser avec des threads qui ne tentent pas d'accéder aux mêmes données.
Comme David Heffernan dit, la concurrentdictionnaire devrait fournir une meilleure performance. Mais, le gain de performance pourrait être négligeable en fonction de la fréquence des threads multiples essayant d'accéder au cache.
using System; using System.Collections.Concurrent; using System.Threading; namespace ConcurrentCollections { class Program { static void Main() { var cache = new ConcurrentDictionary<string, int>(); for (int threadId = 0; threadId < 2; threadId++) { new Thread( () => { while (true) { var newValue = cache.AddOrUpdate("key", 0, (key, value) => value + 1); Console.WriteLine("Thread {0} incremented value to {1}", Thread.CurrentThread.ManagedThreadId, newValue); } }).Start(); } Thread.Sleep(TimeSpan.FromMinutes(2)); } } }
La fonction de mise à jour n'est pas atomique sur un appel addorupdate. msdn.microsoft.com/en-us/library /dd287191(V=VS.110).aspx
Ce commentaire signifie simplement que «le code pourrait fonctionner plus d'une fois avant qu'il réussit». Il tourne en dehors de la serrure, fondamentalement. Donc, il reçoit la valeur existante, ajoute 1 à celui-ci, sort d'une serrure puis essaie de l'écrire. Si la valeur existante a changé entre-temps, il répète le processus jusqu'à ce qu'il réussisse.
Si vous utilisez une liste puis a utilisé une liste list
incrément (list [quoi que ce soit] [0]) code> et le faire atomique. On pourrait améliorer l'efficacité de stockage légèrement si l'une définie
incrémentation (liste REF [ tout] .value) code> pour effectuer l'incrément. Les choses pourraient être plus efficaces encore si les types intégrés fournisaient un moyen d'exposer un élément sous forme de
ref code> ou autorisé les classes dérivées suffisamment accès à leurs internes pour fournir une telle capacité elle-même. Cependant, ils ne doivent toutefois pas définir de ses propres types de collection à partir de zéro ou encapsuler chaque élément de son propre objet de classe [à l'aide d'une matrice ou d'une classe d'emballage]. P> P>
À moins que vous ayez une raison très spécifique à la rédaction de votre propre collection de sécurité de fil dans la plupart des cas, vous serez bien amélioré avec celui fourni avec le TPL.
Pourquoi avez-vous besoin d'une autre manière, si cette voie fonctionne?
Vous recherchez un mécanisme de verrouillage non exclusif?
msdn.microsoft.com/en-us/library/system. filetage.monitor.as px
Je prend du temps pour obtenir le verrouillage global pour verrouiller les fils avant d'incrémenter et la méthode supérieure a peu de frais généraux. La vitesse est une exigence ici et même un peu de frais de plus de 100 millions d'objets ajoute plus de temps.
@CSHARPIE:
verrouillage code> il suffit d'utiliser
moniteur code> sous les capots de toute façon.
@ user1765444: alors peut-être avez-vous besoin d'un spinlock. Voir albahaari.com/threading/partt5.aspx#_spinlock_and_spinwait
Vous pouvez utiliser
concurrentdictionner code>
Vous pouvez utiliser l'une des collections à partir de Espace de noms.Collections.ContCurrent. .
@RoberTharvey, c'est cependant un comportement légèrement différent. Stackoverflow.com/Questtions/2837070/... < / a>
@MichaelPerrenoud: Bien sûr, mais cela n'aura probablement pas d'importance ici.
@RoberTharvey, je suis d'accord à 100% avec cette déclaration, je voulais juste partager cela avec vous parce que je viens de le trouver moi-même lors de la recherche.
Pour être plus rapide qu'un verrou, vous pouvez peut-être réorganiser votre algorithme de sorte que les différents threads n'écrivent pas sur le même élément.