Blazor中await Task.Run(StateHasChanged)与await InvokeAsync(StateHasChanged)的区别
Task.Run(StateHasChanged) 与 InvokeAsync(StateHasChanged) 的核心差异 Blazor所有托管模型通用规则:所有修改组件状态、触发渲染的操作,必须在组件关联的Dispatcher线程上下文中执行,两种写法的差异本质就是对这个规则的符合度不同:
await Task.Run(StateHasChanged)属于非规范写法
该写法会将StateHasChanged调用调度到线程池线程执行,它在普通Blazor WASM环境下看起来正常运行,完全是因为当前版本的Blazor WASM运行时为单线程设计,所有线程池任务最终都会排队到唯一的UI线程执行,属于巧合可用的情况。
一旦运行环境支持多线程(比如bUnit测试环境、Blazor Server、后续支持多线程的WASM runtime),该写法就会抛出你遇到的System.InvalidOperationException异常,因为执行StateHasChanged的线程池线程没有关联组件的Dispatcher。await InvokeAsync(StateHasChanged)属于官方推荐的标准写法InvokeAsync是组件基类内置的API,会始终将传入的委托调度到组件所属的Dispatcher线程上下文执行,完全符合Blazor的状态更新规则,在所有托管模型、所有运行环境下都能稳定工作。
结论
原有项目的写法是不规范的,只适配了当前单线程WASM的特殊环境,存在兼容隐患,建议统一替换为InvokeAsync的写法。
内容的提问来源于stack exchange,提问作者Samuel Carswell
相关产品推荐
相关产品推荐

