Bercovici Adrian
Bercovici Adrian

Reputation: 9360

Blazor Interop causes LOS Overflow

I am using Blazor and i am using interop to call a .NET method from javascript at regular intervals using window.SetInterval.

Calling the .NET method causes laggy-ness and this message in the browser -debug:

Message

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

The js part is pretty straight forward.I have a subscription, a set and a clear interval method that will be called from .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);
    }
}

In .Net i have a method that starts the SetInterval and a method that is JSInvokeable.This invokeable method launches an event to which i subscribe in my component.

Component

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;
}

Basically what i am doing is i have a [Parameter] bool ShouldRefresh that when it changes value i either clear or set the subscription via js interop.When the subscription is set the JSInvokeable method will also publish an event to the parent component.

P.S If i stop invoking the JSInvokeable method from js i stop getting lag and the overflow message.

Upvotes: 1

Views: 982

Answers (1)

enet
enet

Reputation: 45636

@Bercovici Adrian, your code is not complete. Suppose that when your child component is rendered for the first time, and the value assigned to ShouldRefresh equals true: window.methods.setInterval method is called, which calls back the C# RefreshCallbackAsync method that triggers the event JSCalledRefresh... I don't see any code that assign false to JSCalledRefresh, and thus initiate a call to window.methods.clearInterval... As a result, window.methods.setInterval is executed endlessly, calling again and again to the RefreshCallbackAsync method. Perhaps, this is the cause of the exception.

Hope this helps...

Upvotes: 2

Related Questions