在服务器页面渲染页面时如何停止IDisposable调用?

问题描述 投票:0回答:1

这是我的代码:

@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))

可以解决这个问题。我尝试过,但问题仍然存在。我该如何解决?谢谢。

asp.net-core .net-core blazor
1个回答
1
投票

下面的代码段与您的代码段完全一样,对我来说非常好。仅在关闭电路时才调用Dispose方法。我将在下面使用的全部代码发布,复制并运行它,然后尝试为您解决其他问题。

<app>
        @(await Html.RenderComponentAsync<App>(RenderMode.Server))
 </app>

注意:我要在此处发布整个文件的内容。您必须使用自己的应用程序来调整我的应用程序的名称空间。

CircuitHandlerService.cs的代码

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的代码

@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());
    }

当然还有_Host.cshtml

<app>
        @(await Html.RenderComponentAsync<App>(RenderMode.Server))
</app>

请,请不要报告...

© www.soinside.com 2019 - 2024. All rights reserved.