When working with such a simple counter, it is better to use Interlocked.Increment:
private static int s_Number = 0;
public static int GetNextNumber()
{
return Interlocked.Increment(ref s_Number);
}
, ( ) .
:
s_Number- 1
s_Numbers_Number
:
- 1 , , , 1, .
- 1 3 , 4 , , .
, , lock :
private readonly object _SomeLock = new object();
...
lock (_SomeLock)
{
}
, , , - , Interlocked.Increment , .
Interlocked, , .
.
, s_Number 0 :
Thread 1 Thread 2
Read s_Number = 0
Read s_Number = 0
Add 1 to s_Number, getting 1
Add 1 to s_Number, getting 1 (same as thread 1)
Store into s_Number (now 1)
Store into s_Number (now 1)
Read s_Number = 1
Read s_Number = 1
Return read value (1)
Return read value (1)
, s_Number 2, 1, 2. 1, 1. .
Thread 1 Thread 2
Read s_Number = 0
Add 1 to s_Number, getting 1
Store into s_Number (now 1)
Read s_Number = 1
Add 1 to s_Number, getting 2
Store into s_Number (now 2)
Read s_Number = 2
Read s_Number = 2
Return read value (2)
Return read value (2)
s_Number 2, , 1, 2.
, IL. IL
GetNumber:
IL_0000: ldsfld UserQuery.s_Number
IL_0005: ldc.i4.1
IL_0006: add
IL_0007: stsfld UserQuery.s_Number
IL_000C: ldsfld UserQuery.s_Number
IL_0011: ret
. LINQPad, IL , (/o + ), , , IL, LINQPad :
void Main() { }
private static int s_Number = 0;
public static int GetNumber()
{
s_Number++;
return s_Number;
}