gpt4 book ai didi

C# 事件去抖动

转载 作者:IT王子 更新时间:2023-10-29 04:10:06 27 4
gpt4 key购买 nike

我正在收听硬件事件消息,但我需要对其进行去抖动以避免查询过多。

这是一个发送机器状态的硬件事件,我必须将它存储在数据库中以用于统计目的,有时它的状态会经常变化(闪烁?)。在这种情况下,我只想存储一个“稳定”状态,我想通过在将状态存储到数据库之前等待 1-2 秒来实现它。

这是我的代码:

private MachineClass connect()
{
try
{
MachineClass rpc = new MachineClass();
rpc.RxVARxH += eventRxVARxH;
return rpc;
}
catch (Exception e1)
{
log.Error(e1.Message);
return null;
}
}

private void eventRxVARxH(MachineClass Machine)
{
log.Debug("Event fired");
}

我将此行为称为“去抖动”:WAITING几次以真正完成其工作:如果在去抖动时间内再次触发同一事件,我必须取消第一个请求并开始等待去抖动时间以完成第二个事件。

管理它的最佳选择是什么?只是一个一次性计时器?

要解释“去抖动”功能,请查看关键事件的 javascript 实现: http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/

最佳答案

我用它来消除事件并取得了一些成功:

public static Action<T> Debounce<T>(this Action<T> func, int milliseconds = 300)
{
var last = 0;
return arg =>
{
var current = Interlocked.Increment(ref last);
Task.Delay(milliseconds).ContinueWith(task =>
{
if (current == last) func(arg);
task.Dispose();
});
};
}

用法

Action<int> a = (arg) =>
{
// This was successfully debounced...
Console.WriteLine(arg);
};
var debouncedWrapper = a.Debounce<int>();

while (true)
{
var rndVal = rnd.Next(400);
Thread.Sleep(rndVal);
debouncedWrapper(rndVal);
}

它可能不如 RX 中的功能强大,但它易于理解和使用。

跟进 2020-02-03

使用取消 token 修改@collie 的解决方案如下

public static Action<T> Debounce<T>(this Action<T> func, int milliseconds = 300)
{
CancellationTokenSource? cancelTokenSource = null;

return arg =>
{
cancelTokenSource?.Cancel();
cancelTokenSource = new CancellationTokenSource();

Task.Delay(milliseconds, cancelTokenSource.Token)
.ContinueWith(t =>
{
if (t.IsCompletedSuccessfully)
{
func(arg);
}
}, TaskScheduler.Default);
};
}

注意事项:

  • 调用Cancel 足以处理 CTS
  • 成功完成的 CTS 在下一次调用之前不会被取消/处置
  • 正如@collie 所指出的,任务会被释放,因此无需对任务调用 Dispose

我之前没有使用过取消 token ,可能没有正确使用它们。

关于C# 事件去抖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28472205/

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