System.Threading.Tasks.TaskScheduler.Id の .NET 4.0 の実装を見ていると、次のコードが表示されます。
[__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;
}
}
msft がインターロック後に num==0 を比較するのはなぜですか? Interlocked.Increment()の実装は、(インクリメント後に) インクリメントされた値を返すと言っているので、ゼロをチェックする必要はないようです (カウンターがラップアラウンドしない限り、しかしそれが起こった場合、ここでも解決されていないより大きな問題があります.
もし私がそれをするなら、私は単にするだろう:
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;
}
}