Vous dites que vous ne voulez pas utiliser lock
pour des raisons de performances - mais l'avez-vous testé? Un verrou incontesté (ce qui est susceptible d'être, par les sons de celui-ci) est assez bon marché.
Je préfère généralement "évidemment correct" plutôt que "intelligent et peut-être plus performant" quand il s'agit de filetage (et en général, mais surtout pour le filetage). Benchmark votre application avec et sans verrouillage, et voir si vous pouvez même remarquer la différence. Si le verrouillage fait différence significative puis sûr, utilisez des trucs astucieux. Sinon, je resterais avec un verrou.
Une chose que vous pourriez vouloir faire est d'utiliser Interlocked.Increment
avec un int
et juste jeter lorsqu'il est nécessaire d'obtenir un uint
, comme ceci:
using System;
using System.Reflection;
using System.Threading;
public class Test
{
private static int count = int.MaxValue-1;
public static uint IncrementCount()
{
int newValue = Interlocked.Increment(ref count);
return (uint) newValue;
}
public static void Main()
{
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
}
}
Sortie:
2147483647
2147483648
2147483649
(En d'autres termes, il s'enroule sans aucun problème.)
Cela permet de s'assurer que tout changement apporté à la v ariable sont immédiatement réinscrits dans la mémoire, au lieu d'attendre que le thread produise ou que la valeur soit déplacée dans un registre. Il ne protège pas l'accès au champ, c'est-à-dire que deux (ou plus) threads peuvent lire la même valeur, incrémenter une fois, et réécrire, augmentant ainsi la valeur de 1. –
Veuillez lire les exigences ci-dessus ainsi que l'exemple au http: //msdn.microsoft.com/en-us/library/7a2f3ay4.aspx. Pour le cas donné, cela suffit. – Sesh
Quel est le niveau de performance par rapport à Interlocked.Increment? Même? Meilleur? – jrista