Blazor点击加载按钮时禁用另一按钮直到数据加载完成问题
问题根因
这是Blazor同步事件执行机制导致的:同步执行的事件处理方法会全程占用UI线程,哪怕你在方法第一行就修改disableSync值、手动调用StateHasChanged(),组件也必须等整个方法执行完毕后才会统一执行UI重绘。你在方法开头把disableSync设为true,方法执行完又改回false,两次状态变更会被合并到同一次渲染批次里,中间的禁用状态根本不会在UI上呈现。
可行修复方案
把耗时的数据加载逻辑改为异步执行,在修改禁用状态后主动让出UI线程完成渲染,等数据全部加载完成后再解除按钮禁用,具体修改步骤:
- 将
FetchOrder的返回值改为Task,加上async修饰 - 方法开头设置
disableSync = true后,立刻调用StateHasChanged()触发一次UI渲染 - 用
await调度后续的耗时加载逻辑,避免阻塞UI线程 - 所有加载逻辑执行完成后,再将
disableSync设为false
修改后的代码示例:
<button class="btn btn-primary" @onclick="FetchOrder">Compare Data</button> <button class="btn btn-danger" @onclick="SyncOrder" disabled="@disableSync">Sync Eviz data to Monday board</button> @code{ private bool disableSync = true; private async Task FetchOrder(){ // 先标记同步按钮为禁用状态 disableSync = true; // 主动触发UI更新,此时会立刻渲染按钮的禁用态 StateHasChanged(); // 执行耗时数据加载逻辑,不会阻塞UI线程 await Task.Run(() => { // 此处替换为你原来的同步加载逻辑:调用类方法、处理数据等 }); // 数据全部加载完成后,解除同步按钮的禁用状态 disableSync = false; } private void SyncOrder() { // 原有的数据同步保存逻辑 } }
注意:如果你的数据加载逻辑本身提供异步API(比如异步HTTP请求、异步数据库查询),不需要额外包裹
Task.Run,直接await对应异步方法即可,这种实现性能更优,也不会产生额外的线程调度开销。
如果不想改动原有同步逻辑的结构,也可以在设置完disableSync = true和StateHasChanged()后加一行await Task.Delay(1),强制让出一次线程执行权保证UI完成渲染,但这种方式治标不治本,长耗时的同步逻辑依然会阻塞后续UI响应,不推荐在生产环境使用。
内容的提问来源于stack exchange,提问作者Josh E
相关产品推荐
相关产品推荐

