C# 事件去抖

2023-12-03

我正在监听硬件事件消息,但我需要对其进行反跳以避免太多查询。

这是一个发送机器状态的硬件事件,我必须将其存储在数据库中以用于统计目的,有时它的状态会经常变化(闪烁?)。在这种情况下,我只想存储“稳定”状态,并且我想通过在将状态存储到数据库之前简单地等待 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");
}

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

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

要解释“debounce”功能,请参阅以下关键事件的 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();
        });
    };
}

Usage

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

使用取消令牌修改了 @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);
    };
}

Notes:

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

我以前没有使用过取消令牌,可能没有正确使用它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 事件去抖 的相关文章

随机推荐

  • 如何更改 SwiftUI 中导航栏标题的文本属性?

    最近 我一直在尝试新的 SwiftUI 框架 我确实对该框架的工作原理有基本的了解 但我无法找到更改导航栏标题属性的方法 我使用的是最新的 Xcode 11 beta 5 和相应的 swift swiftUI 版本 我已经尝试过一些事情 我
  • C++\CLI 应用程序加载时崩溃

    我有一个 C 应用程序 它加载大量 C DLL 和一些选定的 C CLI DLL 在其中一台计算机 Windows Server 2003 SP2 上启动时收到错误消息 应用程序无法正确初始化 0xC0000005 单击 确定 终止应用程序
  • 如何在没有秒的情况下格式化 MySQL TIMEDIFF?

    我正在运行这个SELECT陈述 TIMEDIFF NOW posts date modified as time ago 并得到格式的结果02 58 32 最后一组数字 32 是秒数 我怎样才能省略秒 SELECT TIME FORMAT
  • iOS 的 Cordova healthkit 插件函数返回未定义?

    我正在尝试使用科尔多瓦插件健康我正在开发的phonegap应用程序的插件 每当我使用该应用程序时 每个插件都可以工作 但这个插件除外 我正在使用phonegap mac 应用程序在iPhone 6s 上进行测试 我已采取的步骤 安装的插件c
  • 仅在根进程上声明的数组

    特别是在 Fortran 的 MPI 中 仅在根进程上定义数组是否可能并且是一个不错的选择 例如这样的事情 program test implicit none include mpif h all mpi init ierr call m
  • 比较两个字符串并返回差异。 Python 3 [重复]

    这个问题在这里已经有答案了 我的目标是编写一个程序来比较两个字符串并显示前两个不匹配字符之间的差异 例子 str1 dog str2 doc 应该返回 gc 我知道我尝试使用的代码很糟糕 但我希望收到一些提示 这是我解决这个练习的糟糕尝试
  • C#性能分析-如何计算CPU周期?

    这是进行性能分析的有效方法吗 我想要获得纳秒精度并确定类型转换的性能 class PerformanceTest static double last 0 0 static List numericGenericData new List
  • 如何创建 html 输入文本区域,以便可以为某些单词添加下划线或设置其格式?

    我想要一个输入字段 我可以让javascript为输入字段的不同部分设置某些属性 一个简单的例子来演示我想做的事情 假设我想在输入文本区域中的所有咒语单词下划线 因此 当插入新字母时 JavaScript 将检查输入文本区域 并且对于与我的
  • RichtextBox 中的粗体

    我一直在研究我的富文本框 但遇到了一些奇怪的事情 我想将每一行的第一个单词加粗 使用此代码 RichTextBox bold richTextBox1 foreach string line in bold Lines string nam
  • 用于向下钻取图表的自己的后退按钮

    我有一个带有向下钻取数据的饼图 是否可以隐藏默认的后退按钮并从我自己的按钮触发后退功能 是的 这是可能的 只需创建您自己的按钮 然后单击调用chart drillUp 功能 看docs Highcharts v5 和 v6 在 Highch
  • AWS RDS 是否支持 MySQL 作为文档存储

    我能够连接普通的AWS RDS MySQL实例 5 7 16 但是 由于我必须使用 MySQL 作为文档存储 因此我通过安装 mysqlx 插件配置了 MySQL 实例 这是文档存储所需的 此后 我尝试连接同一实例上端口 33060 上的
  • YouTube 嵌入视频开始/停止事件

    我想知道 通过 iframe 嵌入 YouTube 视频是否会暴露某些事件 例如 onStart 或 onStop 您可以在其中指定一些回调 这是处理启动和停止事件的示例 HTML 文件 index html
  • 如何在 Spring Boot 中将 Json 字节数组转换为 AMQP?

    按照此 我有这个代码 Bean open fun messageConverter om ObjectMapper MessageConverter return Jackson2JsonMessageConverter om Bean o
  • 在 PySpark 2.0 中读取序列文件

    我有一个序列文件 其值如下所示 string value json value 我不关心字符串值 在 Scala 中我可以通过以下方式读取文件 val reader sc sequenceFile String String path va
  • 如何使用 PyGame 计时器事件?如何使用计时器向 pygame 屏幕添加时钟?

    我是 python 新手 因此决定尝试制作一个简单的游戏pygame 我想添加一个计时器 时钟来显示 你已经玩了 生存了多长时间 所以基本上创建了一个时钟 然而 我四处搜寻并得到了time sleep 1 它确实可以作为时钟使用 但它会减慢
  • 将多个 Intent 从单个 Activity 发送到另一个 Activity

    我对 android 很陌生 我正在尝试将用户输入的数据 他们的名字 发送到另一个活动 我过去能够使用意图在活动之间发送单行 但我无法弄清楚如何将两个不同的字符串发送到两个不同的 TextView 这是到目前为止我的 MainActivit
  • 使用 jQuery 解析 JSON

    我正在尝试使用 jQuery 解析以下 JSON 并获取每个 id 值 有人可以建议吗 id 1 name Boat id 2 name Cable 到目前为止我有 each test function i item alert item
  • 在 R 中查找数组中最接近元素的最快方法

    我想找到 R 中最快的方法来识别 Ytimes 数组中最接近给定 Xtimes 值的元素索引 到目前为止 我一直在使用一个简单的 for 循环 但必须有更好的方法来做到这一点 Xtimes lt c 1 5 8 10 15 19 23 34
  • Swift / 如何使用 popViewController 调用委托

    我读过了这个线程 以及类似的其他 从下到上 但它根本不符合我的需求 我有一个UIViewController inside UIPageViewController在一个UINavigationController 导航到第二个 ViewC
  • C# 事件去抖

    我正在监听硬件事件消息 但我需要对其进行反跳以避免太多查询 这是一个发送机器状态的硬件事件 我必须将其存储在数据库中以用于统计目的 有时它的状态会经常变化 闪烁 在这种情况下 我只想存储 稳定 状态 并且我想通过在将状态存储到数据库之前简单