Blazor Interop вызывает переполнение LOS - PullRequest
1 голос
/ 28 марта 2019

Я использую Blazor и использую interop для вызова .NET метода из javascript через равные промежутки времени, используя window.SetInterval.

Вызов метода .NET вызывает laggy-Несс и это сообщение в браузере -debug:

Сообщение

WASM: GC_MAJOR_SWEEP: major size: 1232K in use: 836K
blazor.webassembly.js:1 WASM: GC_MAJOR: (LOS overflow) time 76.10ms, stw 76.14ms los size: 24464K in use: 23455K
blazor.webassembly.js:1 WASM: GC_MINOR: (LOS overflow) time 19.33ms, stw 19.37ms promoted 0K major size: 1232K in use: 339K los size: 24464K in use: 23455K

Часть js довольно прямолинейна. У меня есть subscription, a set и clear метод интервала, который будет вызываться из .net.

Js

window.methods={

subscription: null,

setInterval: function (interval) {
        if (this.subscription != null || this.subscription != undefined) {
            window.clearInterval(this.subscription);
        }
        subscription = window.setInterval(async function () {
            console.log("calling .net from js");
            await DotNet.invokeMethodAsync("Sms.Studio.Web.Client", "RefreshCallbackAsync");
        }, interval);

    },

clearInterval: function () {
        if (subscription == null || subscription == undefined) {
            return;
        }
        console.log("Clearing subscription");
        window.clearInterval(subscription);
    }
}

В .Net у меня есть метод, который запускаетSetInterval и method, то есть JSInvokeable. Этот вызываемый метод запускает событие, на которое я подписываюсь в моем компоненте.

Компонент

private bool shouldRefresh;
[Parameter] protected bool ShouldRefresh {
        get {
            return this.shouldRefresh;
        }
        set {
             ManageSubscription(value);

        }
    }

public delegate Task OnRefresh();
public static event OnRefresh JSCalledRefresh;

[JSInvokable("RefreshCallbackAsync")]
public static async Task RefreshAsync() {
  Console.WriteLine("Invoked event");
  JSCalledRefresh?.Invoke();

        }

private  void ManageSubscription(bool value) {
  if (this.shouldRefresh == value) {
     return;
  }
  if(this.shouldRefresh==false && value == true) {
     JSMethods.SetInterval(INTERVAL);
     JSCalledRefresh += SubscribeMethod;     
  }
  else if(this.shouldRefresh==true && value == false) {
     JSMethods.ClearInterval();
     JSCalledRefresh -=SubscribeMethod; 
  }
  this.shouldRefresh = value;
}

По сути, у меня есть [Parameter] bool ShouldRefresh, когда при изменении значения я либо clear, либо set подписываюсь через js interop. Когда подписка установлена, метод JSInvokeable также публикует событие вродительский компонент.

PS Если я перестану вызывать метод JSInvokeable из js, то перестану получать задержку и сообщение о переполнении.

1 Ответ

2 голосов
/ 28 марта 2019

@ Bercovici Адриан, ваш код не полный. Предположим, что когда ваш дочерний компонент отображается в первый раз, а значение, назначенное для ShouldRefresh, равно true: вызывается метод window.methods.setInterval, который вызывает метод C # RefreshCallbackAsync, который вызывает событие JSCalledRefresh ... Я не увидеть любой код, который присваивает false значение JSCalledRefresh и, таким образом, инициирует вызов window.methods.clearInterval ... В результате window.methods.setInterval выполняется бесконечно, снова и снова вызывая метод RefreshCallbackAsync. Возможно, это является причиной исключения.

Надеюсь, это поможет ...

...