App.razor添加@code区块遇RZ1006错误,求解决及线程优化方案
解决App.razor中RZ1006错误及标签页非活跃时的线程优化
解决RZ1006代码块闭合错误
针对你遇到的代码块未识别、提示缺少闭合}的问题,可按以下步骤排查:
- 检查HTML标签闭合:确认
<CascadingAuthenticationState>、<Router>等所有Razor标签都成对闭合,避免因标签未关导致Razor解析混乱。 - 校验@code块括号:仔细核对@code内所有方法、变量块的
{和},确保没有全角符号、多余或缺失的括号。 - 转义文本中的特殊字符:如果HTML部分的文本包含
},需用@("}")转义,防止被Razor误判为代码块闭合符。 - 清理项目缓存:删除项目的
bin、obj目录后重新生成解决方案,排除缓存导致的解析异常。
实现标签页非活跃时的线程关闭逻辑
要实现标签页隐藏时关闭后台线程的逻辑,需完善IVisibilityService实现并优化App.razor中的线程管理:
1. 实现IVisibilityService服务
public interface IVisibilityService { event Action OnVisible; event Action OnHidden; Task Initialize(); } public class VisibilityService : IVisibilityService, IDisposable { private readonly IJSRuntime _js; private DotNetObjectReference<VisibilityService> _dotNetRef; private bool _disposed; public event Action OnVisible; public event Action OnHidden; public VisibilityService(IJSRuntime js) { _js = js; } public Task Initialize() { _dotNetRef = DotNetObjectReference.Create(this); return _js.InvokeVoidAsync("registerVisibilityChange", _dotNetRef); } [JSInvokable] public void HandleVisibilityChange(bool isVisible) { if (isVisible) { OnVisible?.Invoke(); } else { OnHidden?.Invoke(); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { _dotNetRef?.Dispose(); _js.InvokeVoidAsync("unregisterVisibilityChange"); } _disposed = true; } }
2. 添加JavaScript监听逻辑
在wwwroot/js/visibility.js中添加:
let visibilityCallback; function registerVisibilityChange(dotNetRef) { visibilityCallback = () => { const isVisible = document.visibilityState === 'visible'; dotNetRef.invokeMethodAsync('HandleVisibilityChange', isVisible); }; document.addEventListener('visibilitychange', visibilityCallback); } function unregisterVisibilityChange() { if (visibilityCallback) { document.removeEventListener('visibilitychange', visibilityCallback); visibilityCallback = null; } }
并在index.html中引入该脚本。
3. 注册服务
在Program.cs中添加服务注册:
builder.Services.AddScoped<IVisibilityService, VisibilityService>();
4. 优化App.razor的线程管理
@inject IVisibilityService VisibilityService @implements IDisposable <CascadingAuthenticationState> <Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> <NotAuthorized> <h1>Access Denied</h1> <p>You are not authorized to access this resource.</p> </NotAuthorized> </AuthorizeRouteView> </Found> <NotFound> <LayoutView Layout="@typeof(MainLayout)"> <p role="alert">Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </CascadingAuthenticationState> @code { private CancellationTokenSource _backgroundCts; private Task _backgroundTask; protected override async Task OnInitializedAsync() { VisibilityService.OnVisible += OnTabVisible; VisibilityService.OnHidden += OnTabHidden; await VisibilityService.Initialize(); // 启动示例后台线程 StartBackgroundTask(); } private void StartBackgroundTask() { _backgroundCts = new CancellationTokenSource(); _backgroundTask = Task.Run(async () => { while (!_backgroundCts.Token.IsCancellationRequested) { // 替换为实际后台业务逻辑 Console.WriteLine("Background task running..."); await Task.Delay(1000, _backgroundCts.Token); } }, _backgroundCts.Token); } private void OnTabVisible() { Console.WriteLine("Tab is visible"); // 标签页恢复时重启后台线程 if (_backgroundCts?.IsCancellationRequested == true) { StartBackgroundTask(); } } private void OnTabHidden() { Console.WriteLine("Tab is hidden"); // 标签页隐藏时取消并释放后台线程资源 _backgroundCts?.Cancel(); _backgroundCts?.Dispose(); _backgroundCts = null; } public void Dispose() { // 清理事件订阅与资源 VisibilityService.OnVisible -= OnTabVisible; VisibilityService.OnHidden -= OnTabHidden; _backgroundCts?.Cancel(); _backgroundCts?.Dispose(); } }
说明:
- 通过
CancellationTokenSource管理后台线程的生命周期,标签页隐藏时取消任务并释放资源,避免内存浪费。 - 实现
IDisposable接口清理事件订阅与令牌资源,防止内存泄漏。 - 替换示例中的后台任务逻辑为你实际的业务线程代码即可。
内容的提问来源于stack exchange,提问作者Przemo
相关产品推荐
相关产品推荐

