.NET 多线程开发总结(四)——借助异步语法实现可延时触发的按钮

14 篇文章 0 订阅

转眼又是一年,作为开年的第一篇博客,先写点简单的热热手,毕竟也好久没写了。

如题,这是一篇实战类型的文章,之所以放到“多线程开发”这个系列来呢,是因为…Emmmm,没有理由,就是想放这(任性**_**)。

进入正题>>>

在日常开发中,会遇到如下一些情况:
①按钮点击后隔一段时间方可再次点击,如:发送验证码
②按钮加载后隔一段时间方可点击,如:阅读条款后已同意按钮
③按钮点击后隔一段时间才会触发事件,如:点击查询按钮后指定时间无响应则主动结束

针对①②两种情况,我们可以联合起来分析,如在Click事件或Load事件触发后禁用按钮一段时间即可。这段代码非常简单,非常符合此篇博客的主题。

public async void DelayToEnable(int milliseconds)
{
    this.IsEnabled = false;
    await Task.Delay(milliseconds);
    this.IsEnabled = true;
}

针对第③种情况,原本也可以用以上方法进行稍作调整来实现,但为了体现封装性,也方便日后使用,所以还是继承Button重写了一些东西。

public class DelayButton : System.Windows.Controls.Button
{
	/// <summary>
    /// 延时启用
    /// </summary>
    /// <param name="milliseconds"></param>
    public async void DelayToEnable(int milliseconds)
    {
        this.IsEnabled = false;
        await Task.Delay(milliseconds);
        this.IsEnabled = true;
    }

    /// <summary>
    /// 取消延时触发的令牌
    /// </summary>
    private CancellationTokenSource m_DelayTriggerCts;

    /// <summary>
    /// 延时触发间隔,单位(ms)
    /// </summary>
    public int DelayTriggerInterval
    {
        get { return (int)GetValue(DelayTriggerIntervalProperty); }
        set { SetValue(DelayTriggerIntervalProperty, value); }
    }

    // Using a DependencyProperty as the backing store for DelayTriggerInterval.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DelayTriggerIntervalProperty =
        DependencyProperty.Register(nameof(DelayTriggerInterval), typeof(int), typeof(DelayButton), new PropertyMetadata(0));

    /// <summary>
    /// 延时触发路由事件
    /// </summary>
    public static readonly RoutedEvent DelayTriggerRoutedEvent =
         EventManager.RegisterRoutedEvent("DelayTrigger", RoutingStrategy.Bubble, typeof(EventHandler<RoutedEventArgs>), typeof(DelayButton));

    public event RoutedEventHandler DelayTrigger
    {
        add { this.AddHandler(DelayTriggerRoutedEvent, value); }
        remove { this.RemoveHandler(DelayTriggerRoutedEvent, value); }
    }

    /// <summary>
    /// 取消延时触发
    /// </summary>
    public void CancelDelayTrigger()
    {
        m_DelayTriggerCts?.Cancel();
    }
    protected override async void OnClick()
    {
        base.OnClick();

        try
        {
            m_DelayTriggerCts = new CancellationTokenSource();
            await Task.Delay(DelayTriggerInterval, m_DelayTriggerCts.Token);
            RoutedEventArgs args = new RoutedEventArgs(DelayTriggerRoutedEvent, this);
            this.RaiseEvent(args);
        }
        catch (Exception)
        {
            Console.WriteLine("The delay trigger has been cancelled.");
        }
        finally
        {
            m_DelayTriggerCts.Dispose();
            m_DelayTriggerCts = null;
        }
    }
}

(增加一个可以手动取消延迟的令牌,可以在长时间的延迟等待过程中随时结束)

上一篇:.NET 多线程开发总结(三)——线程间的信号传递(线程交互)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值