我试图在blazor服务器端应用程序中更改用于标题的字符串。但是我无法更新用户界面。
我尝试使用StateHasChanged(),但是没有用,所以我环顾四周,发现在制作的FlightFinder Demo上,它具有OnChange事件Action,因此我正在尝试实现它。
它一直有效,直到我尝试刷新浏览器,然后才遇到此错误
System.InvalidOperationException:'当前线程未与渲染器的同步上下文关联。触发渲染或修改渲染期间访问的任何状态时,请使用Invoke()或InvokeAsync()将执行切换到渲染器的同步上下文。
这就是我所拥有的:
private string _title = "TestSite";
public string Title => _title;
public event Action OnChange;
public void ChangePage(string pageName)
{
_title = pageName;
NotifyStateChanged();
}
private void NotifyStateChanged(int navigationType = 0)
{
OnChange?.Invoke();
}
我要做的就是调用ChangePage(“some Page Title”),它可以工作,除非像我提到的那样,我尝试刷新。
我只是想通过另一个组件更改一个组件上的字符串,这听起来并不那么疯狂。如果有更好的方法来制作标题或更改其他组件中的内容,我将很乐意听到。
那么,我该怎么做才能确保m调用方法在正确的线程上?
还是有其他更有效的更改标题的方法?
先感谢您!
最佳答案
我刚刚像这样实现了一个状态容器,并遇到了相同的错误-但我的服务需要为单例。
因此,我在aspnetcore git上找到了一个示例,该示例完全执行错误消息说的操作。
调用 InvokeAsync -不是从状态容器中调用,而是在您尝试更改 Razor 组件的状态时调用。
https://github.com/dotnet/aspnetcore/blob/321db9d99f84cf7a67d453384292d9339de748d1/src/Components/test/testassets/BasicTestApp/DispatchingComponent.razor
因此,您的状态容器不需要更改,而组件事件处理程序则需要更改。
@code{
protected override void OnInitialized()
{
_YourService.OnChange += OnMyChangeHandler;
}
public void Dispose()
{
_YourService.OnChange -= OnMyChangeHandler;
}
private async void OnMyChangeHandler(object sender, EventArgs e)
{
// InvokeAsync is inherited, it syncs the call back to the render thread
await InvokeAsync(() => {
DoStuff();
StateHasChanged());
}
}
}
现在,您的服务(如果是单例)可以立即通知您的所有用户!考虑一下我们过去必须跳过的所有步骤。