'How to call particular function after every two mins In Blazor razor component?

I want call particular function after every two mins in blazor. I tried following code

@using System;
@inherits Microsoft.AspNetCore.Components.OwningComponentBase<TestBlazor.Client.APIGateway>

//Html code to display list.

@code{
    private IEnumerable<TestBlazor.Model.Message> MessagesList;

    protected override OnInitialized()
   {

     SetTimer();
   }    

   private void SetTimer()
   {
      var startTimeSpan = TimeSpan.Zero;
      var periodTimeSpan = TimeSpan.FromMinutes(1);

      var timer = new System.Threading.Timer((e) =>
     {
        GetMessage();
     }, null, startTimeSpan, periodTimeSpan);
   } 



   private void GetMessage()
  {
    var filter = new TestBlazor.Model.Filter.MessageFilter()
    {
        Origination = Model.Enums.MessageOrigination.Patient,
        PharmacyId = 1
    };

    MessagesList = Service.MessageService.GetFilteredSummaryAsync(filter).Result;
    MessagesList = MessagesList.Select(x => { x.DateTime = DateTime.Now; return x; }).ToList();

    base.InvokeAsync(StateHasChanged);
  }
}

This is working as expected but problem is when I navigate to other component and again come back to this Message component then I am getting following exception

Cannot access a disposed object. Object name: 'Messages' where 'Messages' is Razor component name.It will be helpful if anybody could tell me what exactly I am doing wrong? or Is there any other solution for this?



Solution 1:[1]

The problem is that your timer continues to run even when the component is already removed from the view. In that case, the timer will just try to access the component instance (because it still has a reference to it), and call the GetMessage which will eventually make an operation on the component that will not work because the component has actually been disposed.

What you should do is to make sure that you free up all resources when the component is removed. You can do that by implementing IDisposable with your component. Usually, this would look like this:

@implements IDisposable

@code {
     private Timer _timer;

     protected override void OnInitialized()
     {
         _timer = new Timer(…);
     }

     public void Dispose()
     {
         _timer?.Dispose();
     }
}

Since your component inherits from OwningComponentBase which already implements IDisposable itself, you will need to extend the disposal of your component:

@inherits OwningComponentBase<TestBlazor.Client.APIGateway>

@code {
     private Timer _timer;

     protected override void OnInitialized()
     {
         _timer = new Timer(…);
     }

     protected override void Dispose(bool disposing)
     {
         _timer?.Dispose();
     }
}

Solution 2:[2]

Code below worked in Blazor Wasam .NET6

protected override async Task OnInitializedAsync()
{
    //set timer
    var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));

    while (await timer.WaitForNextTickAsync())
    {
        //do something here every 10s
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 poke
Solution 2 user160357