I want to increment an unsigned integer from multiple threads.
I know about Interlocked.Increment, but it does not handle unsigned integers. I could use lock(), but I would rather not if possible for performance reasons.
Is it thread safe just to increment it in the normal way? It would not matter if the occasional increment got lost, as it's only used for statistics. What I don't want is the value to get corrupted.
You say you don't want to use lock
for performance reasons - but have you tested it? An uncontested lock (which this is likely to be, by the sounds of it) is pretty cheap.
I generally go for "obviously correct" rather than "clever and possibly better performing" when it comes to threading (and in general, but especially for threading).
Benchmark your app with and without locking, and see whether you can even notice the difference. If locking makes a significant difference then sure, use cunning stuff. Otherwise, I'd just stick with a lock.
One thing you might want to do is use Interlocked.Increment
with an int
and just cast it when necessary to get a uint
, like this:
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 unchecked((uint) newValue);
}
public static void Main()
{
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
}
}
Output:
2147483647
2147483648
2147483649
(In other words it wraps with no problems.)