这是我的代码:
@page "/" @using Microsoft.AspNetCore.Components.Server.Circuits @inject CircuitHandler circuitHandler @implements IDisposable <h1>Hello, world!</h1> Welcome to your new app. @code{ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { Console.WriteLine("123");//do something } } #region//circuitHandler protected override void OnInitialized() { // Subscribe to the event handler (circuitHandler as CircuitHandlerService).CircuitsChanged += HandleCircuitsChanged; } public void HandleCircuitsChanged(object sender, EventArgs args) { Console.WriteLine("123");//do something } public void Dispose() { (circuitHandler as CircuitHandlerService).CircuitsChanged -= HandleCircuitsChanged; } #endregion }using Microsoft.AspNetCore.Components.Server.Circuits; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace BlazorApp2 { public class CircuitHandlerService : CircuitHandler { public ConcurrentDictionary<string, Circuit> Circuits { get; set; } public event EventHandler CircuitsChanged; protected virtual void OnCircuitsChanged() => CircuitsChanged?.Invoke(this, EventArgs.Empty); public CircuitHandlerService() { Circuits = new ConcurrentDictionary<string, Circuit>(); } public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken) { Circuits[circuit.Id] = circuit; //OnCircuitsChanged(); return base.OnCircuitOpenedAsync(circuit, cancellationToken); } public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken) { Circuit circuitRemoved; Circuits.TryRemove(circuit.Id, out circuitRemoved); OnCircuitsChanged(); return base.OnCircuitClosedAsync(circuit, cancellationToken); } public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken) { return base.OnConnectionDownAsync(circuit, cancellationToken); } public override Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken) { return base.OnConnectionUpAsync(circuit, cancellationToken); } } }
我需要 CircuitHandler 来了解页面是否关闭。 现在我遇到了一个奇怪的问题。加载页面后,即使页面未关闭, IDisposable 也会始终调用。 而且, OnAfterRenderAsync 中有一些代码。调用 IDisposable 时,未运行完毕的 OnAfterRenderAsync 中的代码会突然中断而不会出现任何错误。 有人告诉我设置
I need the CircuitHandler to get to know whether the page is closed. Now I met a strange problem. When the page is loaded, the IDisposable always invoke even the page is not closed. What's more, there are several codes in OnAfterRenderAsync. When the IDisposable invokes, the codes in OnAfterRenderAsync which not runs finished will suddenly break without any error. Someone told me to set the
@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))在 _Host.cshtml中到
@(await Html.RenderComponentAsync<App>(RenderMode.Server))可以解决这个问题。 我尝试过,但问题仍然存在。 我该如何解决?谢谢。
can solve this. I tried, but the problem still here. How can I solve this? Thank you.
推荐答案下面的代码段与您的代码段完全一样,并且对我来说非常好。仅在关闭电路时才调用Dispose方法。我将在下面使用的全部代码下面发布,复制并运行它,然后尝试为您解决其他问题。
the code snippet below is exactly like yours, and it works for me perfectly fine. The Dispose method is called only when a Circuit is closed. I'll post below the entire code I use, copy and run it, then I'll try to help with other issues you have.
<app> @(await Html.RenderComponentAsync<App>(RenderMode.Server)) </app>注意:我在此处发布整个文件的内容。您必须使用自己的应用程序来调整我的应用程序的命名空间。
Note: I'm posting here entire files' content. You'll have to adjust the namespaces of my app with yours.
using Microsoft.AspNetCore.Components.Server.Circuits; using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; namespace BlazorCircuitHandler.Services { public class CircuitHandlerService : CircuitHandler { public ConcurrentDictionary<string, Circuit> Circuits { get; set; } public event EventHandler CircuitsChanged; protected virtual void OnCircuitsChanged() => CircuitsChanged?.Invoke(this, EventArgs.Empty); public CircuitHandlerService() { Circuits = new ConcurrentDictionary<string, Circuit>(); } public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken) { Circuits[circuit.Id] = circuit; OnCircuitsChanged(); return base.OnCircuitOpenedAsync(circuit, cancellationToken); } public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken) { Circuit circuitRemoved; Circuits.TryRemove(circuit.Id, out circuitRemoved); OnCircuitsChanged(); return base.OnCircuitClosedAsync(circuit, cancellationToken); } public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken) { return base.OnConnectionDownAsync(circuit, cancellationToken); } public override Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken) { return base.OnConnectionUpAsync(circuit, cancellationToken); } } }代码Index.razor
Code for Index.razor
@page "/" @using Microsoft.AspNetCore.Components.Server.Circuits @using BlazorCircuitHandler.Services @inject CircuitHandler circuitHandler @implements IDisposable <p> Number of Circuits: @((circuitHandler as BlazorCircuitHandler.Services.CircuitHandlerService).Circuits.Count) <ul> @foreach (var circuit in (circuitHandler as BlazorCircuitHandler.Services.CircuitHandlerService).Circuits) { <li>@circuit.Key</li> } </ul> </p> @code { protected override void OnInitialized() { (circuitHandler as CircuitHandlerService).CircuitsChanged += HandleCircuitsChanged; } public void Dispose() { (circuitHandler as CircuitHandlerService).CircuitsChanged -= HandleCircuitsChanged; } public void HandleCircuitsChanged(object sender, EventArgs args) { InvokeAsync(() => StateHasChanged()); } }也有初创班
Also Startup class
public void ConfigureServices(IServiceCollection services) { // Removed for brevity.... services.AddSingleton<CircuitHandler>(new CircuitHandlerService()); }当然还有_Host.cshtml
And of course _Host.cshtml
<app> @(await Html.RenderComponentAsync<App>(RenderMode.Server)) </app>请不要报告...
更多推荐
在blazor服务器端呈现页面时,如何停止IDisposable调用?
发布评论