代码之家  ›  专栏  ›  技术社区  ›  KreonZZ

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

  •  0
  • KreonZZ  · 技术社区  · 6 年前

    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(async env)的可能性-有没有任何方法可以使递减工作与自定义条件避免吨的IFs(我需要保持错误率>=0)?

    1 回复  |  直到 6 年前
        1
  •  1
  •   ckuri    6 年前

    你可以使用 CompareExchange pattern 对于更复杂的操作:

    int initialErrorRate, int computedErrorRate;
    do
    {
      initialErrorRate = errorRate;
      if (increase)
      {
        computedErrorRate = initialErrorRate + 1;
      }
      else
      {
        computedErrorRate = initialErrorRate - Convert.ToInt32(initialErrorRate > 0);
      }
    }
    // set new error rate only when it was not changed inbetween, otherwise try again
    while (initialErrorRate != Interlocked.CompareExchange(ref errorRate, computedErrorRate, initialErrorRate);
    
    if (errorRate > 50)
    {
      TimerStop(true);
    }