Blazor异步函数实时数据绑定场景UI无法逐次更新该如何解决?
问题原因
- Blazor默认仅会在组件事件处理逻辑全部执行完成后自动触发一次UI重渲染,你当前的循环逻辑被包裹在
Task.Run的委托中,整个Count方法要等20次循环全部跑完才会执行完毕,中间修改counter值不会自动触发UI更新 - 原有代码中
Task.Delay(500).Wait()是同步阻塞写法,不符合异步编程规范,也会占用线程资源
解决方案
你可以调用Blazor组件内置的StateHasChanged()方法主动触发UI重渲染,同时优化异步写法,修正后代码如下:
<p>@counter</p> <button @onclick="Count">Count</button> @code { private int counter; private async Task Count() { counter = 0; // 可选,每次点击重置计数 for (var i = 0; i < 20; i++) { counter++; Console.WriteLine("counter = " + counter); // 主动触发UI重渲染 StateHasChanged(); // 异步等待避免线程阻塞 await Task.Delay(500); } } }
如果你的业务场景必须要在Task.Run的后台线程中修改状态,需要通过InvokeAsync方法把StateHasChanged的调用调度到UI线程上下文执行,避免线程安全问题,代码示例:
<p>@counter</p> <button @onclick="Count">Count</button> @code { private int counter; private async Task Count() { await Task.Run(async () => { for (var i = 0; i < 20; i++) { counter++; Console.WriteLine("counter = " + counter); // 调度到UI线程触发重渲染 await InvokeAsync(StateHasChanged); await Task.Delay(500); } }); } }
内容的提问来源于stack exchange,提问作者Seti Seti
相关产品推荐
相关产品推荐

