我创建了一个简单的类,显示我正在尝试做什么,没有任何噪音。 随时打开我的代码。这就是我在这里发布的原因。有没有更好的方法来抑制高吞吐量的工作?
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();
}
}
}
}
您的代码缺少开始执行的公共方法。 – Vlad 2010-03-11 23:34:00
@弗拉德 - 谢谢。 – ChaosPandion 2010-03-11 23:35:53
根据文档(http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx),您不需要保护'ManualResetEvent':它是线程安全的。 – Vlad 2010-03-11 23:39:10