如何在C#中检查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在递增时可能会溢出(在异常大的输入上),在这种情况下我想抛出一个异常(提前崩溃以便于调试)。

微软文档摘录:

此方法通过包装处理溢出条件:如果location=Int32.MaxValue,则location + 1=Int32.MinValue。没有引发异常。

只需检查newId是否为Int32.MinValue(在转换为uint之前)并引发异常。

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

考虑使用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. 更简单、更小的代码

相关内容

  • 没有找到相关文章

最新更新