我有一个需要每 1 分钟显示新鲜数据的组件。
我尝试了新的计时器(周期性计时器),它工作正常。
现在,我的问题是,
放置 while 循环的最佳位置在哪里?
正确处置 PeriodicTimer 还需要其他东西吗?
public partial class Index:IDisposable
{
private readonly PeriodicTimer _periodicTimer = new(TimeSpan.FromMinutes(1));
protected override async Task OnInitializedAsync()
{
await Service.Init();
while (await _periodicTimer.WaitForNextTickAsync())
{
await Service.GetViewModels();
await InvokeAsync(StateHasChanged);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_periodicTimer.Dispose();
}
}
}
如果我把代码放在Index
,即 statup 页面,它永远不会完成加载。
如果我把 code 在另一个页面,它看起来像它运行良好,但它不是。
问题是OnInitializedAsync
永远不会完成。它总是在while
循环中等待。因此,初始组件生命周期的其余部分也没有完成。
作为启动页面,它被锁定在初始服务器负载中。
要解决这个问题,你需要“火,忘记”定时器循环。
这里有一个演示组件,以及如何使用“旧”定时器与事件处理程序(我个人会坚持)。
@page "/Test"
@implements IDisposable
<h1>Hello</h1>
<div class="m-2">
Message: @message
</div>
<div class="m-2">
Timer Message: @timerMessage
</div>
<div class="m-2">
@state
</div>
@code {
private System.Timers.Timer timer = new System.Timers.Timer(2000);
private readonly PeriodicTimer _periodicTimer = new(TimeSpan.FromSeconds(5));
private string message = "Starting";
private string timerMessage = "Starting";
private string state = "On Init Running";
// This is broken code
//protected override async Task OnInitializedAsync()
//{
// while (await _periodicTimer.WaitForNextTickAsync())
// {
// message = $"Updated at {DateTime.Now.ToLongTimeString()}";
// await InvokeAsync(StateHasChanged);
// }
//}
protected override void OnInitialized()
{
RunTimer();
state = "On Init complete";
// Uses System.Timers.Timer
timer.Elapsed += TimeElapsed;
timer.AutoReset = true;
timer.Enabled = true;
}
private async void TimeElapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
// emulate an async data get
await Task.Delay(100);
timerMessage = $"Updated at {DateTime.Now.ToLongTimeString()}";
await InvokeAsync(StateHasChanged);
}
protected async void RunTimer()
{
while (await _periodicTimer.WaitForNextTickAsync())
{
// emulate an async data get
await Task.Delay(100);
message = $"Updated at {DateTime.Now.ToLongTimeString()}";
await InvokeAsync(StateHasChanged);
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_periodicTimer.Dispose();
timer.Elapsed -= TimeElapsed;
}
}
}
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(2条)