在blazor服务器端呈现页面时,如何停止IDisposable调用? [英] How can I stop IDisposable invokes while render the page in blazor server-side?

查看:106
本文介绍了在blazor服务器端呈现页面时,如何停止IDisposable调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

@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调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆