gpt4 book ai didi

c# - 有没有更好的方法来限制高吞吐量作业?

转载 作者:行者123 更新时间:2023-11-30 12:53:24 25 4
gpt4 key购买 nike

我创建了一个简单的类来显示我正在尝试做的事情,没有任何噪音。随意抨击我的代码。这就是我将它发布在这里的原因。

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() 之前轻松完成。

然后,我会让工作线程与主线程不同,从而解除对其他任务的主线程的阻塞。接下来,我将添加一个函数来取消处理,这可能会设置一个检查工作线程的标志。

编辑:
根据评论,我们的目标是在每个 throttlePeriod 节拍期间限制 work() 调用的次数。我们可以通过记下秒表中的时间,在 throttleLimit work 操作之后比较它,然后休眠剩余时间来做得更好。这样我们就不再需要计时器线程了。

编辑:(已删除,不正确)
编辑:
我们甚至可以做某种平衡:在 throttlePeriod 内,我们计算 work() 花费了多少时间,因此我们可以估计剩余的时间work() 将占用并等待 每个 两个 work() 之间的剩余时间。这将使我们不会在分配周期开始时非常快地执行所有 work(),可能会阻塞 DB。

关于c# - 有没有更好的方法来限制高吞吐量作业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2429414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com