首页 > 解决方案 > 如何防止 Blazor 服务器端页面冻结?

问题描述

我有一组与 gRPC 服务器通信的应用程序。这些应用程序在 Blazor 服务器端运行,一切正常,几乎!!!它应该几乎像本地聊天一样工作。我在一台机器上写一件事,所有其他机器接收并显示它。为了显示它,我有一个计时器来检查应用程序自己的 gRPC 服务是否接收到任何内容,我将该数据抓取到页面变量中,并且调用状态已更改。问题是页面在一段时间后冻结。当没有人在他们身上工作时,它总是会发生。而且我没有收到任何错误。有人可以帮帮我吗???????????

页面代码:

@code {
    bool registred = false;
    int countLogingAttempts = 2;
    string Name = "first name";
    public string displayLoader = "block";
    public string displayQueuesContainer = "none";
    private string Time { get; set; }
    public System.Threading.Timer LoginTimer { get; set; }
    public string[] queueNames = new string[0];
    public int[] queueNumbers = new int[0];
    public int countStateChanged = 0;
    string selectedQueueName = "";

    string SelectedQueueName
    {
        get => selectedQueueName;
        set
        {
            selectedQueueName = value;

        }
    }

    public bool[] displayQueues = new bool[4] { false, false, false, false };

    protected override void OnInitialized()
    {
        jsRuntime.InvokeAsync<string>("console.log", "intilializing " + countLogingAttempts);
        LoginTimer = new System.Threading.Timer((_) =>
        {
            jsRuntime.InvokeAsync<string>("console.log", "Tiking");
            if (!registred)
            {

                int capturedint = countLogingAttempts;
                jsRuntime.InvokeAsync<string>("console.log", "Trying " + capturedint);
                if (countLogingAttempts == 5)
                {
                    Task.Run(() => SayHello());
                    countLogingAttempts = 0;
                    jsRuntime.InvokeAsync<string>("console.log", "Say hello ");
                }

                countLogingAttempts += 1;
            }
            else
            {
                displayLoader = "none";
                displayQueuesContainer = "block";
                InvokeAsync(StateHasChanged);
                updatePage();
                jsRuntime.InvokeAsync<string>("console.log", "Disposed" + countLogingAttempts);
                LoginTimer.Dispose();
            }
        }, null, 0, 1000);
    }

    public void updatePage()
    {
        var timer = new System.Threading.Timer((_) =>
        {
            if (registred)
            {
                Time = DateTime.Now.ToString("HH:mm");
                jsRuntime.InvokeAsync<string>("console.log", "Registred." + countLogingAttempts);
                queueNames = GreeterService1.queueNames;
                queueNumbers = GreeterService1.queueNumbers;
                InvokeAsync(StateHasChanged);
            }

        }, null, 0, 1000);
    }


    async Task SayHello()
    {
        this.registred = await this.GreeterService1.SayHello(this.Name);
        await jsRuntime.InvokeAsync<string>("console.log", "waiting for hello " + registred);
    }

一些标记:

<div class="col col-sm-auto col-clock">
            <div style="margin-right:0px;width: 125px;">
                <h5 id="clock">@Time</h5>
            </div>
        </div>

<div class="container-fluid main-container">
    <div class="row main-row">
        <div id="queueContainer" class="col col-md-auto senhas-col">
            @if (queueNames!=null) {

                if (queueNames.Length>0) {
                    <div class="row senhas-row">
                        <div class="queue-name-div">
                            <a class="queue-name-a ">@queueNames[0]</a>

gRPC 服务:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Logging;
using GrpcConsole;
using BlazorViewer;
using BlazorViewer.Data;

namespace GrpcService1
{
    public class GreeterService : QueueManagement.QueueManagementBase
    {
        public static string clientName="Initial name";
        public string[] queueNames;
        public int[] queueNumbers;
        public static string calledQueue { get; set; }
        public static string publicAuthToken = "token";
        public static bool serviceStatus = false;
        public static string token = "token";
        public static string guidId = "viewer1";
        public static string kind = "viewer";
        public static int numberInKind = 1;
        public static string serverIp = "192.168.5.56";



        public async Task<bool> SayHello(string name)
        {
            bool awnser = false;
            Task t = Task.Run(async () => {
                var httpClientHandler = new HttpClientHandler();
                // Return `true` to allow certificates that are untrusted/invalid
                httpClientHandler.ServerCertificateCustomValidationCallback =
                    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
                var httpClient = new HttpClient(httpClientHandler);
                var channel = GrpcChannel.ForAddress("https://"+serverIp+":5001"
                    , new GrpcChannelOptions { HttpClient = httpClient });
                var client = new QueueManagement.QueueManagementClient(channel);
                IdMessage message = new IdMessage { Token = token, GuidId = guidId, Kind = kind, NumberInKind = numberInKind };
                var request = await client.GeneralRegistryRequestAsync(new RegistryRequest { Identification = message });

                awnser = request.RequestAccepted;
            });
            t.Wait();
            Console.WriteLine("Registry made = "+ awnser);
            return await Task.FromResult(awnser);
        }

        public static void ProcessServiceStatus(bool status)
        {
            serviceStatus = status ? true : false;
        }

        public override async Task<RequestResponse> UpdateToViewer(ViewerUpdate request, ServerCallContext context)
        {

            RequestResponse resp = new RequestResponse { RequestAccepted = false };
            if (request.Token == publicAuthToken)
            {
                resp.RequestAccepted = true;
                ProcessServiceStatus(request.ServiceStatus);
                string[] queueNames1 = request.QueueNames.ToArray();
                int[] queueNumbers1 = request.QueueNumbers.ToArray();

                queueNames = new string[queueNames1.Length];
                queueNumbers = new int[queueNames1.Length];
                queueNames = queueNames1;
                queueNumbers = queueNumbers1;
                Console.WriteLine("Received queues:");
                foreach (var item in queueNames)
                {
                    Console.WriteLine(item);
                }

            }
            return await Task.FromResult(resp);
        }
    }
}

启动文件:

namespace BlazorViewer
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddSingleton<GreeterService>();
            services.AddGrpc();
            services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<GreeterService>();
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }
    }
}

标签: blazor

解决方案


推荐阅读