I have the following code. In windows server 2008, the program is correct and runs as expected. It outputs 10 different ids.
However, when I run it in windows server 2003, the program is not correct. It outputs 10 ids, but some of the id's are duplicates. It seems that the lock is not working.
If I set Thread.Sleep(500)
, it works correctly on windows server 2003.
class Test
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(Util.GetId());
}
Console.ReadLine();
}
}
public class Util
{
private static object idlock = new object();
public static string GetId()
{
string id = "";
lock (idlock)
{
Thread.Sleep(1);
id = System.DateTime.Now.ToString("yyMMddHHmmssffff");
}
return id;
}
}
Locking is completely unnecessary; the problem is that DateTime.Now
only has a granularity of ~15ms or so (depending on your system). Don't use time as an id in the first place; you could easily just do something like this instead:
public static class Util
{
static long _id;
public static string GetId()
{
return Next().ToString("0000000000000000");
}
private static long Next()
{
return Interlocked.Increment(ref _id);
}
}