这是我的代码:
@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
中未运行完毕的代码将突然中断而不会出现任何错误。
有人告诉我设置
@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
在_Host.cshtml
至
@(await Html.RenderComponentAsync<App>(RenderMode.Server))
可以解决这个问题。
我尝试过,但问题仍然存在。
我该如何解决?谢谢。
答案 0 :(得分:2)
下面的代码段与您的代码段完全一样,对我来说非常好。仅在关闭电路时才调用Dispose方法。我将在下面使用的全部代码发布,复制并运行它,然后尝试解决您遇到的其他问题。
<app>
@(await Html.RenderComponentAsync<App>(RenderMode.Server))
</app>
注意:我要在此处发布整个文件的内容。您必须使用自己的应用程序来调整我的应用程序的名称空间。
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);
}
}
}
@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());
}
}
public void ConfigureServices(IServiceCollection services)
{
// Removed for brevity....
services.AddSingleton<CircuitHandler>(new CircuitHandlerService());
}
<app>
@(await Html.RenderComponentAsync<App>(RenderMode.Server))
</app>
请不要报告...