具有自定义条件的Interlocked.Exchange(),依赖于读取锁定的变量

时间:2018-08-18 21:46:59

标签: c# thread-safety interlocked

原始代码:

var can = rateLock.WaitAsync();
if (can.IsCompletedSuccessfully) // for safety but do I need it?
{
    if (!increase)
    {
        errorRate = (byte)(errorRate - Convert.ToByte(errorRate > 0));
    }
    else
    {
        errorRate++;
    }
    if (errorRate > 50)
    {
        TimerStop(true);
    }
    rateLock.Release();

}

修改为:

if (increase)
{
    if (Interlocked.Increment(ref errorRate) > 50)
    {
        TimerStop(true);
    }
}
else
{
    Interlocked.Exchange(ref errorRate, (errorRate - Convert.ToInt32(errorRate > 0)));
}

问题: 如您所见,“递减”部分依赖于需要读取两次的相同变量值,然后执行布尔和减法运算,而所有这些都在互锁上下文之外。

我真的很喜欢没有额外的SempahoreSlim(异步环境)的可能性-有什么方法可以使自定义条件下的递减工作避免大量的IF(我需要保持errorRate> = 0)?

1 个答案:

答案 0 :(得分:1)

您可以使用CompareExchange pattern进行更复杂的操作:

set JAVA_HOME=C:\Softwares\Java\Java-6\jdk1.6.0_41
set PATH=%PATH%;%JAVA_HOME%\bin

set GRAILS_HOME=C:\Softwares\Grails\Grails_2.1.0
set PATH=%PATH%;%GRAILS_HOME%\bin

cd /D C:\MyWorkspace\MyApplication

grails run-app

REM pause