在不阻塞 UI 的情况下延迟 Blazor 中的任务
Delay a task in Blazor without blocking the UI
我在 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 任务?
带有倒计时计时器的组件
<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 中的行为应该相同。
希望这有帮助
您也可以使用 System.Timers
中的 .NET Timer
并以毫秒为单位设置延迟。当它过去时,事件将被触发,您可以将您的逻辑放入事件处理程序中。如果你不想打扰 Timer
的所有配置和处理,你可以使用这个 Nuget package. It is a very convenient wrapper for the Timer with many extra features see docs.
<AdvancedTimer Occurring="Times.Once()" IntervalInMilisec="@_closeInMs" AutoStart="true" OnIntervalElapsed="@(e => { IsVisible = false; })" />
@code {
private int _closeInMs = 5000;
...
}
我在 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 任务?
带有倒计时计时器的组件
<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 中的行为应该相同。 希望这有帮助
您也可以使用 System.Timers
中的 .NET Timer
并以毫秒为单位设置延迟。当它过去时,事件将被触发,您可以将您的逻辑放入事件处理程序中。如果你不想打扰 Timer
的所有配置和处理,你可以使用这个 Nuget package. It is a very convenient wrapper for the Timer with many extra features see docs.
<AdvancedTimer Occurring="Times.Once()" IntervalInMilisec="@_closeInMs" AutoStart="true" OnIntervalElapsed="@(e => { IsVisible = false; })" />
@code {
private int _closeInMs = 5000;
...
}