2

我正在使用简洁的RateGate 类来限制我发送到服务器的请求数。

我的代码看起来像这样:

var RateLimit = 35;

using(var RateGate = new RateGate(RateLimit, TimeSpan.FromSeconds(1)))
{
    for(var Run = 1; Run <= 50; Run++)
    {
        for(var Batch = 0; Batch < 200; Batch++)
        {
            // Do some work, then...

            MyClass MyClass;

            if(MyClass.RateLimitHit)
            {
                RateLimit--;
            }

            RateGate.WaitToProceed();
        }
    }
}

在内部if(MyClass.RateLimitHit),我需要将速率限制降低 1。不仅仅是变量RateLimit,还有实际运行的限制RateGate

在 RateGate 类中,我看到了这个:

/// <summary>
/// Number of occurrences allowed per unit of time.
/// </summary>
public int Occurrences { get; private set; }

我的问题是:如果我更改private set;set;并添加RateGate.Occurrences = RateLimit;之后RateLimit--;,这会做我想要的吗?

我试过了,但它看起来RateGate继续以 35/s 的最大速率执行。

4

2 回答 2

4

我也想这样做,我通过反转时间和发生率找到了一个很好的解决方案。这是什么意思:

我没有将我的问题表达为“我希望每秒出现 N 次”,而是将其反转为“我希望每 1/N 秒出现 1 次”。这样,我可以轻松更改时间单位,而不是修改出现次数(始终为 1)。我将此方法添加到类中(您也可以派生):

private object _updateTimeUnitLock = new object();
private int nextUpdateTime = 0;
public bool UpdateTimeUnit(TimeSpan timeUnit, TimeSpan dontUpdateBefore)
{
    lock (_updateTimeUnitLock)
    {
        if ((nextUpdateTime == 0) || (nextUpdateTime <= Environment.TickCount))
        {
            TimeUnitMilliseconds = (int)timeUnit.TotalMilliseconds;
            nextUpdateTime = Environment.TickCount + (int)dontUpdateBefore.TotalMilliseconds;

            return true;
        }

        return false;
    }
}

我的必须是线程安全的,我需要一种方法来防止在某些时期发生变化,所以在你这边你可能想要删除锁和dontUpdateBefore参数,这意味着你可以设置 TimeUnitMilliseconds 并且这个值将在下一个计时器滴答时被拾取. 现在,要调用它,您只需要根据您想要的出现次数来计算您想要的新时间。

希望它能满足您的需求。

N。

于 2013-10-28T19:47:31.987 回答
1

Occurrences值作为最大计数传递给构造函数中的信号量,因此更改属性不会影响该实例的行为。

public RateGate(int occurrences, TimeSpan timeUnit)
{
    // Snipped all the code that doesn't pertain to this question...

    Occurrences = occurrences;

    // Create the semaphore, with the number of occurrences as the maximum count.
    _semaphore = new SemaphoreSlim(Occurrences, Occurrences);
}

看起来 Occurrences 更像是一个只读属性,它允许您查看传递给构造函数的内容。

于 2013-10-25T02:37:05.597 回答