Blazor计时器调用异步API任务以更新UI
我正在Blazor服务器端页面中设置计时器。目标是每x秒调用一个API,并根据返回值更新UI 我得到了这个密码:Blazor计时器调用异步API任务以更新UI,blazor,blazor-server-side,Blazor,Blazor Server Side,我正在Blazor服务器端页面中设置计时器。目标是每x秒调用一个API,并根据返回值更新UI 我得到了这个密码: private string Time { get; set; } protected override void OnInitialized() { var timer = new System.Threading.Timer((_) => { Time = DateTime.Now.ToString(); InvokeAsy
private string Time { get; set; }
protected override void OnInitialized()
{
var timer = new System.Threading.Timer((_) =>
{
Time = DateTime.Now.ToString();
InvokeAsync(() =>
{
StateHasChanged();
});
}, null, 0, 1000);
base.OnInitialized();
}
private string Time { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
var timer = new System.Threading.Timer((_) =>
{
InvokeAsync( async () =>
{
Time = await GetValue();
StateHasChanged();
});
}, null, 0, 1000);
}
这个很好用。UI每秒更新一次新的时间值。但是,我不知道如何调用异步任务来获取值。我想换一条线:
Time = DateTime.Now.ToString();
使用调用以下函数的行:
private async Task<string> GetValue()
{
var result = await _api.GetAsync<StringDto>("/api/GetValue");
return result.Text;
}
但我收到了以下错误:
The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
调用异步方法需要做什么
非常感谢 请尝试以下代码:
private string Time { get; set; }
protected override void OnInitialized()
{
var timer = new System.Threading.Timer((_) =>
{
Time = DateTime.Now.ToString();
InvokeAsync(() =>
{
StateHasChanged();
});
}, null, 0, 1000);
base.OnInitialized();
}
private string Time { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
var timer = new System.Threading.Timer((_) =>
{
InvokeAsync( async () =>
{
Time = await GetValue();
StateHasChanged();
});
}, null, 0, 1000);
}
GetValue方法应为:
private async Task<string> GetValue()
{
return await _api.GetAsync<StringDto>("/api/GetValue");
}
请尝试以下代码:
private string Time { get; set; }
protected override void OnInitialized()
{
var timer = new System.Threading.Timer((_) =>
{
Time = DateTime.Now.ToString();
InvokeAsync(() =>
{
StateHasChanged();
});
}, null, 0, 1000);
base.OnInitialized();
}
private string Time { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
var timer = new System.Threading.Timer((_) =>
{
InvokeAsync( async () =>
{
Time = await GetValue();
StateHasChanged();
});
}, null, 0, 1000);
}
GetValue方法应为:
private async Task<string> GetValue()
{
return await _api.GetAsync<StringDto>("/api/GetValue");
}
您可能不想调用GetValue,这将是毫无意义的。您可以这样实现计时器:
System.Threading.Timer timer;
protected override void OnInitialized()
{
timer = new System.Threading.Timer(async _ =>
{
Time = await GetValue();
await InvokeAsync(StateHasChanged);
}, null, 0, 1000);
}
我使用了一个字段来存储计时器,因为您应该处理它,请将此添加到Razor部分:
@implements IDisposable
这与守则有关:
public void Dispose()
{
timer?.Dispose();
}
您可能不想调用GetValue,这将是毫无意义的。您可以这样实现计时器:
System.Threading.Timer timer;
protected override void OnInitialized()
{
timer = new System.Threading.Timer(async _ =>
{
Time = await GetValue();
await InvokeAsync(StateHasChanged);
}, null, 0, 1000);
}
我使用了一个字段来存储计时器,因为您应该处理它,请将此添加到Razor部分:
@implements IDisposable
这与守则有关:
public void Dispose()
{
timer?.Dispose();
}
我喜欢你答案中的一般解决方案,但你是否打算省略对base.OnInitialized的调用?是的,在普通页面中不需要。你可以根据“一般原则”把它放进去,这是品味的问题。请看天气预报页面以获取参考。我喜欢你回答中的一般解决方案,但你是否打算省略呼叫基地。初始化?是的,在正常页面中不需要。你可以根据“一般原则”把它放进去,这是品味的问题。查看天气预报页面以获取参考。