在 Blazor 中,`await Task.Run(StateHasChanged)` 和 `await InvokeAsync(StateHasChanged)` 有什么区别?
In Blazor what is the difference between `await Task.Run(StateHasChanged)` and `await InvokeAsync(StateHasChanged)`?
我最近继承了一个 Blazor Webassembly 应用程序,但是对 dotnet 或 Blazor 的经验很少。
一些组件使用 await Task.Run(StateHasChanged)
而不是 await InvokeAsync(StateHasChanged)
,我想知道这是否是故意的。
我问 await Task.Run(StateHasChanged);
在尝试使用 bUnit 渲染组件时出现以下异常:
System.InvalidOperationException The current thread is not associated
with the Dispatcher. Use InvokeAsync() to switch execution to the
Dispatcher when triggering rendering or component state.
将此更改为 await InvokeAsync(StateHasChanged);
允许组件在 bUnit 中呈现。但是,据我所知,将应用程序用于 await Task.Run(StateHasChanged)
或 await InvokeAsync(StateHasChanged)
.
时,组件的功能相同
这两种调用方法有什么区别StateHasChanged
?
as far as I can tell, the component functions identically ...
没错。 Task.Run(job)
将 运行 ThreadPool 上的作业。然而,在 WebAssembly 中,没有额外的线程,主(唯一)线程迟早必须 运行 这项工作。
在 Blazor Server 中你有线程。 Task.Run()
将在那里工作,但 StateHasChanged()
必须 运行 在主线程上。也就是说
await Task.Run(StateHasChanged) // bug! Don't do this.
绝对是一个错误,无处不在。它暂时在 WebAssembly 上没有引起注意。直到 Blazor Wasm 也获得线程的那一天,它才会抛出。
所以 bUnit 是正确的,修正你的代码。
请注意,在 'normal' 生命周期事件(如 OnInitialized[Async]、OnClick、OnSubmit 等)中,您根本不必使用 InvokeAsync()
。
我通常只使用
StateHasChanged();
并在外部事件(例如计时器)或线程代码(在服务器上)中
await InvokeAsync(StateHasChanged);
我最近继承了一个 Blazor Webassembly 应用程序,但是对 dotnet 或 Blazor 的经验很少。
一些组件使用 await Task.Run(StateHasChanged)
而不是 await InvokeAsync(StateHasChanged)
,我想知道这是否是故意的。
我问 await Task.Run(StateHasChanged);
在尝试使用 bUnit 渲染组件时出现以下异常:
System.InvalidOperationException The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
将此更改为 await InvokeAsync(StateHasChanged);
允许组件在 bUnit 中呈现。但是,据我所知,将应用程序用于 await Task.Run(StateHasChanged)
或 await InvokeAsync(StateHasChanged)
.
这两种调用方法有什么区别StateHasChanged
?
as far as I can tell, the component functions identically ...
没错。 Task.Run(job)
将 运行 ThreadPool 上的作业。然而,在 WebAssembly 中,没有额外的线程,主(唯一)线程迟早必须 运行 这项工作。
在 Blazor Server 中你有线程。 Task.Run()
将在那里工作,但 StateHasChanged()
必须 运行 在主线程上。也就是说
await Task.Run(StateHasChanged) // bug! Don't do this.
绝对是一个错误,无处不在。它暂时在 WebAssembly 上没有引起注意。直到 Blazor Wasm 也获得线程的那一天,它才会抛出。
所以 bUnit 是正确的,修正你的代码。
请注意,在 'normal' 生命周期事件(如 OnInitialized[Async]、OnClick、OnSubmit 等)中,您根本不必使用 InvokeAsync()
。
我通常只使用
StateHasChanged();
并在外部事件(例如计时器)或线程代码(在服务器上)中
await InvokeAsync(StateHasChanged);