如何在 C# 中检查 Interlocked.Increment 后是否溢出?

Suz*_*ron 2 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

鉴于我每次运行生成的 ID 数量相当大,(在异常大的输入上)_counter增量时可能会溢出,并且我想在这种情况下抛出异常(尽早崩溃以简化调试)。

摘自微软的文档

location此方法通过包装: if = Int32.MaxValue, location + 1=来处理溢出情况Int32.MinValue。没有抛出异常。

SLa*_*aks 6

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

MinValue获得增量的唯一方法是通过溢出。

  • 你说得对,那里没有任何问题。__其他:__当他的代码出现在问题中时,他只是将 32 位有符号整数重新解释为_无符号_ 32 位整数,并且他能够获取最多为“4'294'967'295”的 ID。因此,如果我们假设他没有使用“/checked”编译器选项构建代码,那么他的原始代码运行良好。如果他使用你的答案,他只能(大约)生成以前可以生成的 ID 的一半。 (4认同)
  • @JeppeStigNielsen:那么其中一个会溢出,另一个不会。“Interlocked.Increment”的全部要点在于它是原子的;那不是问题。 (2认同)