blazor服务器应用程序中的频繁页面更新
在blazor服务器应用程序中,可以经常发送事件并调用blazor服务器应用程序中的频繁页面更新,blazor,blazor-server-side,Blazor,Blazor Server Side,在blazor服务器应用程序中,可以经常发送事件并调用statehaschange,例如每秒500次吗 我的一个页面需要对外部事件做出反应,然后相应地更新其状态。我找到了以下解决方案: 创建一个检测外部事件并调用C#事件的服务 将服务注入razor页面 在页面中,连接到事件并在处理程序中调用InvokeAsync(()=>StateHasChanged()) 这已经正常工作了。但是,该事件可能经常发生,例如每秒500次,我担心客户端和服务器的性能。不幸的是,我不知道哪一部分发生在服务器上,哪
statehaschange
,例如每秒500次吗
我的一个页面需要对外部事件做出反应,然后相应地更新其状态。我找到了以下解决方案:
- 创建一个检测外部事件并调用C#事件的服务
- 将服务注入razor页面
- 在页面中,连接到事件并在处理程序中调用
InvokeAsync(()=>StateHasChanged())
- 这些事件是否每秒从服务器发送500次到客户端?我认为这将消耗大量带宽
- 客户端是否在每次调用
后实际呈现页面?我认为这会给客户端带来很高的CPU负载statehaschange
- 为了回答您的一些问题,当您在服务器模式下运行时,所有实际工作都在Blazor Hub会话中进行
调用
StateHasChanged
真正做的是将RenderFragment
排队到中心会话中的渲染器队列中。下面是ComponentBase
中的代码位
_renderFragment = builder =>
{
_hasPendingQueuedRender = false;
_hasNeverRendered = false;
BuildRenderTree(builder);
};
状态已更改
如下所示:
protected void StateHasChanged()
{
if (_hasPendingQueuedRender) return;
if (_hasNeverRendered || ShouldRender())
{
_hasPendingQueuedRender = true;
try
{
_renderHandle.Render(_renderFragment);
}
catch
{
_hasPendingQueuedRender = false;
throw;
}
}
}
StateHasChanged
仅在新渲染事件尚未排队时对其排队。渲染后,渲染器扩散引擎会检测到任何更改,并通过Signal将这些更改发送到客户端浏览器会话
所以没有变化,没有客户机活动,只有大量服务器绑定的活动来处理事件并解决任何变化。对服务器的影响将取决于您可用的服务器功率。要回答您的一些问题,在服务器模式下运行时,所有实际工作都将在Blazor Hub会话中进行 调用
StateHasChanged
真正做的是将RenderFragment
排队到中心会话中的渲染器队列中。下面是ComponentBase
中的代码位
_renderFragment = builder =>
{
_hasPendingQueuedRender = false;
_hasNeverRendered = false;
BuildRenderTree(builder);
};
状态已更改
如下所示:
protected void StateHasChanged()
{
if (_hasPendingQueuedRender) return;
if (_hasNeverRendered || ShouldRender())
{
_hasPendingQueuedRender = true;
try
{
_renderHandle.Render(_renderFragment);
}
catch
{
_hasPendingQueuedRender = false;
throw;
}
}
}
StateHasChanged
仅在新渲染事件尚未排队时对其排队。渲染后,渲染器扩散引擎会检测到任何更改,并通过Signal将这些更改发送到客户端浏览器会话
所以没有变化,没有客户机活动,只有大量服务器绑定的活动来处理事件并解决任何变化。对服务器的影响将取决于您可用的服务器功率。看来Blazor服务器每秒可以发送数百个更改:
@page/“
每秒Tics:@CurrentValue
@DateTime.Now.ToString(“HH:mm:ss”)
渲染数量:@nRenders.ToString(“N0”)
开始
.球{宽度:30px;高度:30px;顶部:-10px;
位置:绝对;背景色:蓝色;}
@代码
{
Int64 nRenders=0,v=1,位置=10,电流值=10;
字符串位置_txt=>$“左:{position}px;”;
private static System.Timers.Timer aTimer=new System.Timers.Timer();
受保护的void start()
{
move();
aTimer.appead+=(源代码,e)=>move();
aTimer.AutoReset=true;
aTimer.Enabled=!aTimer.Enabled;
}
受保护的无效移动()
{
aTimer.间隔=1000.0/当前值;
位置=(位置+v);
如果(位置>500 | |位置nRenders++);
}
看来Blazor服务器每秒可以发送数百个更改:
@page/“
每秒Tics:@CurrentValue
@DateTime.Now.ToString(“HH:mm:ss”)
渲染数量:@nRenders.ToString(“N0”)
开始
.球{宽度:30px;高度:30px;顶部:-10px;
位置:绝对;背景色:蓝色;}
@代码
{
Int64 nRenders=0,v=1,位置=10,电流值=10;
字符串位置_txt=>$“左:{position}px;”;
private static System.Timers.Timer aTimer=new System.Timers.Timer();
受保护的void start()
{
move();
aTimer.appead+=(源代码,e)=>move();
aTimer.AutoReset=true;
aTimer.Enabled=!aTimer.Enabled;
}
受保护的无效移动()
{
aTimer.间隔=1000.0/当前值;
位置=(位置+v);
如果(位置>500 | |位置nRenders++);
}
你也有一个每秒可以查看500次的用户吗?@HenkHolterman否我不:)我真的不想那么频繁地更新GUI。但是,只需连接到事件并调用StateHasChanged就很容易了。它是(有一点)收集多个事件并一起处理它们需要做更多的工作。因此,如果blazor已经执行了一些状态已更改的缓冲,我不需要重新实施我自己的策略。您是否也有一个每秒可以查看500次的用户?@Henkholtman否我不:)我真的不想那么频繁地更新GUI。但是,只需连接到事件并调用StateHasChanged就很容易了。它是(一点点)收集多个事件并一起处理它们需要做更多的工作。因此,如果blazor已经执行了一些StateHasChanged的缓冲,我不需要重新实现我自己的策略。hasPendingQueuedRender逻辑是这里最大的保证。查看渲染启动的频率仍然很有趣。不确定这个答案。有一个队列,但也有一种刷新队列的方法(例如在任务结束时)。如果每秒刷新队列500次会发生什么情况?队列用于将更改存储在非渲染块中(例如:任务内部)@daniherrera-此处的队列始终为@HenkHolterman的长度,您知道statehaschange
不会强制渲染,只是标记了要渲染的组件。