前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF开发中的防抖和节流

WPF开发中的防抖和节流

作者头像
码客说
发布2023-12-22 15:38:07
2460
发布2023-12-22 15:38:07
举报
文章被收录于专栏:码客码客

前言

假如我们有一个上线用户的界面,每个用户上线的时候都会做一定的业务处理和页面刷新。

这样如果在短时间内用户大量进入就会导致页面处理不过来,而产生未响应甚至闪退。

这就要用到防抖和节流了。

它们都用在事件频繁触发并且允许丢失的场景下。

防抖和节流都是为了防止事件频发触发的一种方式。

函数防抖(debounce)

当持续触发某事件时,一定时间间隔内没有再触发事件时,事件处理函数才会执行一次,如果设定的时间间隔到来之前,又一次触发了事件,就重新开始延时。 可以保证最后的事件一定触发,但是可能中间可能新事件一直有,则一直取消触发。

函数节流(throttle)

当持续触发事件时,有规律的每隔一个时间间隔执行一次事件处理函数。 可以保证事件流中稳定的触发事件,但是不能保证最后的事件一定被触发。

函数防抖(debounce)

针对用户上线的场景适用防抖更加合适。

在 C# 页面渲染中,防抖处理通常用于限制用户频繁触发某个操作(如按钮点击、输入框输入等)时的请求或处理次数,以提高系统性能和用户体验。

不带参数

页面内的渲染方法基本上都不是静态的,并且参数可以使用页面的私有参数,方法本身不用传参数。

页面中

代码语言:javascript
复制
private readonly Action _renderPage;
public AttendanceWindow()
{
    //页面初始化时初始化防抖对象
    _renderPage = new ZDebounceUtil().Create(RenderUserList, TimeSpan.FromSeconds(0.5));
}

private void RenderUserList()
{
    Dispatcher.Invoke(
        () =>
        {
            //UI渲染
        }
    );
}

//频繁触发的方法
public void UserListChange()
{
    //原来调用RenderUserList()改成如下
    _renderPage?.Invoke();
}

工具类

ZDebounceUtil.cs

代码语言:javascript
复制
using System;
using System.Threading;

public class ZDebounceUtil
{
    private Timer _timer;
    private Action _action;
    private TimeSpan _timeout;

    private void DebouncedAction()
    {
        _timer?.Dispose();
        _timer = new Timer(
            state =>
            {
                _action();
            },
            null,
            _timeout,
            TimeSpan.FromMilliseconds(-1)
        );
    }

    public Action Create(Action action, TimeSpan timeout)
    {
        _action = action;
        _timeout = timeout;
        return DebouncedAction;
    }
}

带参数示例

下面是一个示例代码,

代码语言:javascript
复制
static void Main(string[] args)
{
    Action<string> renderPage = new Debounce<string>().Create(RenderUserList, TimeSpan.FromSeconds(0.5));

    // 模拟用户频繁触发页面渲染的情况
    for (int i = 1; i <= 10; i++)
    {
        renderPage.Invoke($"Page {i}");
    }

    // 防抖处理后,只会执行最后一次调用
    // 输出:Page 10
}

static void RenderUserList(string pageName)
{
    Console.WriteLine($"Rendering {pageName}...");
    // 实际的页面渲染逻辑
}

防抖工具类

代码语言:javascript
复制
using System;
using System.Threading;

public class Debounce<T>
{
    private Timer _timer;
    private Action<T> _action;

    public Action<T> Create(Action<T> action, TimeSpan timeout)
    {
        _action = action;
        return DebouncedAction;
        void DebouncedAction(T param)
        {
            _timer?.Dispose();
            _timer = new Timer(
                state =>
                {
                    _action(param);
                },
                null,
                timeout,
                TimeSpan.FromMilliseconds(-1)
            );
        }
    }
}

在此示例中,我们定义了一个名为 Debounce<T> 的通用类。

通过调用 Create 方法,我们可以创建一个经过防抖处理的函数。

当调用 renderPage.Invoke(pageName) 时,会在指定的时间间隔内只执行最后一次调用。

Render 方法中,我们模拟了实际的页面渲染逻辑,你可以根据实际情况进行修改。

函数节流(throttle)

不带参数

页面中

代码语言:javascript
复制
private readonly Action _renderPage;
public AttendanceWindow()
{
    //页面初始化时初始化节流对象
    _renderPage = new ZThrottleUtil().Create(RenderUserList, TimeSpan.FromSeconds(0.5));
}

private void RenderUserList()
{
    Dispatcher.Invoke(
        () =>
        {
            //UI渲染
        }
    );
}

//频繁触发的方法
public void UserListChange()
{
    //原来调用RenderUserList()改成如下
    _renderPage.Invoke();
}

工具类

ZThrottleUtil.cs

代码语言:javascript
复制
using System;
using System.Threading;

public class ZThrottleUtil {
    private Timer _timer;
    private Action _action;
    private TimeSpan _timeout;

    private void ThrottleAction()
    {
        if (_timer != null)
        {
            return;
        }
        _timer = new Timer(
            state =>
            {
                _action();
                _timer?.Dispose();
                _timer = null;
            },
            null,
            _timeout,
            TimeSpan.FromMilliseconds(-1)
        );
    }

    public Action Create(Action action, TimeSpan timeout)
    {
        _action = action;
        _timeout = timeout;
        return ThrottleAction;
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 函数防抖(debounce)
    • 不带参数
      • 带参数示例
      • 函数节流(throttle)
        • 不带参数
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档