C# 如何检测联锁系统中的溢出(或下溢)。添加

C# 如何检测联锁系统中的溢出(或下溢)。添加,c#,.net,multithreading,interlocked,C#,.net,Multithreading,Interlocked,我想使用Interlocked.Add方法,因为int和long的速度更快。对于其他类型,我有以下代码: short x = Sum(source, range.Item1, range.Item2); checked { lock (syncRoot) result += x; } 但我发现Interlocked不能处理溢出。如何确定发生了溢出或下溢x可以是正的,也可以是负的

我想使用
Interlocked.Add
方法,因为
int
long
的速度更快。对于其他类型,我有以下代码:

short x = Sum(source, range.Item1, range.Item2);
checked
{   
    lock (syncRoot)
        result += x;                                          
} 
但我发现Interlocked不能处理溢出。如何确定发生了溢出或下溢<代码>x可以是正的,也可以是负的

var x = Sum(source, range.Item1, range.Item2);
Interlocked.Add(ref result, x);
bool overflow = ...
if (overflow)
   throw new OverflowException();
我在MSDN上找到了以下提示,但不知道如何实施此检查:

此方法通过包装处理溢出条件:如果 location1为Int32.MaxValue,值为1,结果为 Int32.MinValue;如果值为2,则结果为(Int32.MinValue+1);和 依此类推。不会引发异常


联锁。添加
返回新值。如果新值小于旧值,则会发生溢出。问题是,您无法通过这种方式获得旧值

可以使用自动读取旧值、检查溢出和自动写入新值


请注意,这两个锁都不是互锁操作。联锁操作仅为硬件锁。就绝对值而言,它们的速度更快,而且不会受到竞争的影响。但是,以高频率执行此操作根本不会从多个CPU中受益。

如果必须重新创建所有边界,那么速度也不会更快。
check
无法使用
double
,它只检查整数溢出。要检查溢出:
Double.IsInfinity
@DmitryBychenko您是对的。我为每种数字类型生成代码(因为在.Net中没有数字的通用约束),这就是为什么我得到这个无效代码的原因。我应该编辑我的模板文件。这是非常基本的,你不能检测溢出。jitter将Interlocked.Add()替换为实现原子增量的处理器特定指令。就像英特尔/Amd处理器上的锁XADD。这类指令没有在溢出时生成错误的种类。读测试写操作不是原子操作。Interlocked类只适用于微优化代码,这种代码通常具有尖锐的边缘,如果需要检测溢出,则必须使用lock关键字。我只是在分区上拆分一个集合,然后计算每个分区的总和。然后,我将所有结果汇总到一个结果值中。因此,执行线程的数量不会超过调用的数量,但我希望尽可能避免
lock
。在这种情况下如何实现CAS?不幸的是,这个问题似乎没有意义,因为几次锁定所需的时间非常少。如果你想继续优化它,那么谷歌搜索“.NETCAS循环”或“CAS循环”就可以了。看起来我找到了一个Java实现。我来试试这个:那个代码看起来很奇怪,而且已经坏了。这应该更好:如果您感兴趣: