在C#中使用Interlocked.Increment后如何检查溢出?

时间:2013-07-22 15:15:12

标签: c# integer-overflow interlocked interlocked-increment

调用Interlocked.Increment后检查溢出的正确方法是什么?

我有一个ID生成器,在程序执行期间生成唯一ID,目前我测试它返回零的增量。

public static class IdGenerator {
    private static int _counter = 0;

    public static uint GetNewId() {
        uint newId = (uint)System.Threading.Interlocked.Increment(ref _counter);
        if (newId == 0) {
             throw new System.Exception("Whoops, ran out of identifiers");
        }
        return newId;
    }
}

鉴于我每次运行生成的ID数量相当大,可能(在特别大的输入上)_counter在递增时会溢出,我想在这种情况下抛出异常(崩溃)早期轻松调试)。

摘自Microsoft's documentation

  

此方法通过换行来处理溢出情况:if location = Int32.MaxValuelocation + 1 = Int32.MinValue。没有例外。

2 个答案:

答案 0 :(得分:4)

只需检查newIdInt32.MinValue(在转换为uint之前)并抛出异常。

从增量中获取MinValue的唯一方法是通过溢出。

答案 1 :(得分:0)

考虑使用unchecked

public static class IdGenerator
{
    private static int _counter;

    public static uint GetNewId()
    {
        uint newId = unchecked ((uint) System.Threading.Interlocked.Increment(ref _counter));
        if (newId == 0)
        {
            throw new System.Exception("Whoops, ran out of identifiers");
        }
        return newId;
    }
}

在这种情况下,你得到

  1. 性能提升不大,因为编译器不会检查溢出。
  2. x2密钥空间
  3. 更简单更小的代码