C# 在Blazor中维护嵌套(不是第一个或最后一个)方法的SynchronizationContext 使用VisualStudio 2019加载的默认项目,当在磊科3.1中创建新的BLAZOR服务器端项目时,请考虑下面的示例(对自己的反例页稍作更改):
第一个按钮和标签很简单,只要按一个按钮,用户界面上的计数就会按预期更新。但是,第二个按钮更复杂 中间的C# 在Blazor中维护嵌套(不是第一个或最后一个)方法的SynchronizationContext 使用VisualStudio 2019加载的默认项目,当在磊科3.1中创建新的BLAZOR服务器端项目时,请考虑下面的示例(对自己的反例页稍作更改):,c#,blazor,blazor-server-side,C#,Blazor,Blazor Server Side,第一个按钮和标签很简单,只要按一个按钮,用户界面上的计数就会按预期更新。但是,第二个按钮更复杂 中间的wait-NestedUpdate(++nestedCounter)调用不会反映在UI上。第一个调用和最后一个调用(第一个和最后一个嵌套方法调用)都实时反映在UI上,因此您看到的是: Update from nested method: 1 *2 seconds go by Update from nested method: 3 我意识到这是因为SynchronizationContext的
wait-NestedUpdate(++nestedCounter)
调用不会反映在UI上。第一个调用和最后一个调用(第一个和最后一个嵌套方法调用)都实时反映在UI上,因此您看到的是:
Update from nested method: 1
*2 seconds go by
Update from nested method: 3
我意识到这是因为SynchronizationContext
的警告,但我更好奇的是如何捕获和维护该上下文,以便在我的按钮按下事件中调用的每个等待的方法都使用相同的上下文,以便UI在代码执行时实时更新。有没有一个好的/漂亮的方法可以做到这一点
我意识到这是因为SynchronizationContext的警告
不,不是真的。所有这些代码都应该在主线程上异步但按顺序运行。
这里的SyncContext没有错误或需要修复
您看到的是StateHasChanged()逻辑,它实际上是关于一个状态的,可能只是一个布尔标志
BLAZOR框架会在调用EvEnthANDER之前和之后设置这个标志,但是在中间,你必须这样做。
快速修复和解释:
protected async Task NestedMethodUpdate()
{
// the flag is pre-set here
await NestedUpdate(++nestedCounter);
// the thread is available and Blazor will render '1' and reset the flag
await Task.Delay(1000);
await NestedUpdate(++nestedCounter);
// the thread is available but the flag is down: the '2' is not shown
await Task.Delay(1000);
await NestedUpdate(++nestedCounter);
StatehasChanged(); // <<-- add this
// the thread is available and the flag is up: the '3' is shown
await Task.Delay(1000);
// you can add more steps
await NestedUpdate(++nestedCounter);
StatehasChanged(); // <<-- set the flag
await Task.Delay(1000); // show '4'
// this result will show '5' after the method has completed
await NestedUpdate(++nestedCounter);
}
NestedMethodUpdate()受保护的异步任务
{
//此标志在此处预设
等待NesteUpdate(++nestedCounter);
//线程可用,Blazor将呈现“1”并重置标志
等待任务。延迟(1000);
等待NesteUpdate(++nestedCounter);
//线程可用,但标志已关闭:“2”未显示
等待任务。延迟(1000);
等待NesteUpdate(++nestedCounter);
StatehasChanged();//ConfigureAwait(true)
也许吧?@Henkholtman你是什么意思?啊,我明白了!我注意到前后的方法都呈现得很好,但现在这很有意义!StatehasChanged的行为是否只会在任何地方记录的方法的开头和结尾自动应用?
Update from nested method: 1
*2 seconds go by
Update from nested method: 3
protected async Task NestedMethodUpdate()
{
// the flag is pre-set here
await NestedUpdate(++nestedCounter);
// the thread is available and Blazor will render '1' and reset the flag
await Task.Delay(1000);
await NestedUpdate(++nestedCounter);
// the thread is available but the flag is down: the '2' is not shown
await Task.Delay(1000);
await NestedUpdate(++nestedCounter);
StatehasChanged(); // <<-- add this
// the thread is available and the flag is up: the '3' is shown
await Task.Delay(1000);
// you can add more steps
await NestedUpdate(++nestedCounter);
StatehasChanged(); // <<-- set the flag
await Task.Delay(1000); // show '4'
// this result will show '5' after the method has completed
await NestedUpdate(++nestedCounter);
}