【问题标题】:Delay a task in Blazor without blocking the UI在不阻塞 UI 的情况下延迟 Blazor 中的任务
【发布时间】:2020-02-06 06:19:08
【问题描述】:

我在 Blazor 中创建了一个 .razor 通知组件,并尝试在 xx 秒后自动关闭通知 div。

到目前为止,它适用于这个方法

 private async Task CloseToast(Guid Id, bool autoclose = false)
{
    if (autoclose)
    {
        await Task.Delay(TimeSpan.FromSeconds(5));
    }

   //Code to remove the notification from list
    StateHasChanged();
}

问题是 UI 数据绑定卡住了 5 秒,对变量(文本字段等)的任何一种或两种方式绑定更新都被暂停,直到通知关闭并且任务恢复。

如何在 xx 秒后启动方法或代码块而不阻塞 Blazor 中的主 UI 任务?

【问题讨论】:

    标签: asp.net-core blazor blazor-server-side


    【解决方案1】:

    带有倒计时计时器的组件

    
    <h3>@Time</h3>
    
    @code {
        [Parameter] public int Time { get; set; } = 5;
    
        public async void StartTimerAsync()
        {
            while (Time > 0)
            {
                Time--;
                StateHasChanged();
                await Task.Delay(1000);
            }
        }
    
        protected override void OnInitialized()
            => StartTimerAsync();
    }
    

    用法:

    <Component />
    <Component Time="7"/>
    

    在客户端 Blazor 上测试。在服务器端 Blazor 中的行为方式应该相同。 希望这会有所帮助

    【讨论】:

    • 我不明白。有什么区别?为什么 OP 的代码会阻塞而你的不会?
    • 方法签名中的async void 有所不同。 async void 基本上是一劳永逸,而async Task 将等到整个任务完成。其他选择是使用具有相同async void 方式的 System.Timer.Timer 类而不是 while 循环。
    • async Task 也不应该阻塞用户界面。问题不完整。
    【解决方案2】:

    您也可以使用来自System.Timers 的.NET Timer,并以毫秒为单位设置延迟。当它过去时,将触发事件,您可以将逻辑放入事件处理程序中。如果你不想打扰Timer 的所有配置和处理,你可以使用这个Nuget package。它是一个非常方便的定时器包装器,具有许多额外的功能see docs

    <AdvancedTimer Occurring="Times.Once()" IntervalInMilisec="@_closeInMs" AutoStart="true" OnIntervalElapsed="@(e => { IsVisible = false; })" />
    @code {
      private int _closeInMs = 5000;
      ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      相关资源
      最近更新 更多