I’m looking at the System.Threading.Tasks.TaskScheduler.Id implementation of .NET 4.0, and see the following code:
[__DynamicallyInvokable]
public int Id
{
[__DynamicallyInvokable]
get
{
if (this.m_taskSchedulerId == 0)
{
int num = 0;
do
{
num = Interlocked.Increment(ref s_taskSchedulerIdCounter);
}
while (num == 0);
Interlocked.CompareExchange(ref this.m_taskSchedulerId, num, 0);
}
return this.m_taskSchedulerId;
}
}
why does msft compare the num==0 after the interlocked? The implementation of Interlocked.Increment() says it returns the incremented value (after incrementing) so seems unnessicary to check for zero (unless your counter wraps around, but if that happens you have bigger problems that are also not resolved here.
If I were to do it, i’d simply do:
public int Id
{
get
{
if(m_taskSchedulerId==0)
{
var result = Interlocked.Increment(ref s_taskSchedulerIdCounter);
Interlocked.CompareExchange(ref m_taskSchedulerId, result, 0);
}
return m_taskSchedulerId;
}
}
No, that’s the exact reason they do this. From the Reference Source: