我创建了一个简单的类,它展示了我正在尝试做的事情,没有任何噪音。
请随意攻击我的代码。这就是我将其发布在这里的原因。
public class Throttled : IDisposable
{
private readonly Action work;
private readonly Func<bool> stop;
private readonly ManualResetEvent continueProcessing;
private readonly Timer throttleTimer;
private readonly int throttlePeriod;
private readonly int throttleLimit;
private int totalProcessed;
public Throttled(Action work, Func<bool> stop, int throttlePeriod, int throttleLimit)
{
this.work = work;
this.stop = stop;
this.throttlePeriod = throttlePeriod;
this.throttleLimit = throttleLimit;
continueProcessing = new ManualResetEvent(true);
throttleTimer = new Timer(ThrottleUpdate, null, throttlePeriod, throttlePeriod);
}
public void Dispose()
{
throttleTimer.Dispose();
((IDisposable)continueProcessing).Dispose();
}
public void Execute()
{
while (!stop())
{
if (Interlocked.Increment(ref totalProcessed) > throttleLimit)
{
lock (continueProcessing)
{
continueProcessing.Reset();
}
if (!continueProcessing.WaitOne(throttlePeriod))
{
throw new TimeoutException();
}
}
work();
}
}
private void ThrottleUpdate(object state)
{
Interlocked.Exchange(ref totalProcessed, 0);
lock (continueProcessing)
{
continueProcessing.Set();
}
}
}
最新代码
public class Throttled
{
private readonly Func<bool> work;
private readonly ThrottleSettings settings;
private readonly Stopwatch stopwatch;
private int totalProcessed;
public Throttled(Func<bool> work, ThrottleSettings settings)
{
this.work = work;
this.settings = settings;
stopwatch = new Stopwatch();
}
private void Execute()
{
stopwatch.Start();
while (work())
{
if (++totalProcessed > settings.Limit)
{
var timeLeft = (int)(settings.Period - stopwatch.ElapsedMilliseconds);
if (timeLeft > 0)
{
Thread.Sleep(timeLeft);
}
totalProcessed = 0;
stopwatch.Reset();
stopwatch.Start();
}
}
}
}
首先,我会完全摆脱控制线程,因为它的工作可以在调用之前轻松完成work()
.
然后,我将使工作线程与主线程不同,从而为其他任务解除主线程的阻塞。接下来,我将添加一个函数来取消处理,这可能会设置一个检查工作线程的标志。
Edit:
根据评论,我们的目标是限制数量work()
每次通话期间throttlePeriod
滴答声。我们可以通过记下秒表中的时间来做得更好,然后进行比较throttleLimit
工作操作,剩下的时间就是睡觉。这样我们就不再需要计时器线程了。
编辑:(已删除,不正确)
Edit:
我们甚至可以做某种平衡:处于一个throttlePeriod
,我们计算花了多少时间work()
花费,所以我们可以估计剩余的时间work()
s 将采取并等待each two work()
剩余时间均等。这将使我们无法执行所有work()
在分配周期开始时速度非常快,可能会阻塞数据库。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)