Как вызывать определенную функцию через каждые две минуты в компоненте бритвы Blazor? - PullRequest
0 голосов
/ 05 мая 2020

Я хочу вызывать определенную функцию через каждые две минуты в Blazor. Я пробовал следующий код

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

Он работает, как ожидалось, но проблема в том, что когда я перехожу к другому компоненту и снова возвращаюсь к этому компоненту сообщения, я получаю следующее исключение

Нет доступа к удаленному объекту. Имя объекта: «Сообщения» , где «Сообщения» - это имя компонента Razor. Было бы полезно, если бы кто-нибудь мог сказать мне, что именно я делаю не так? или есть ли другое решение для этого?

1 Ответ

1 голос
/ 05 мая 2020

Проблема в том, что ваш таймер продолжает работать, даже если компонент уже удален из представления. В этом случае таймер просто попытается получить доступ к экземпляру компонента (потому что у него все еще есть ссылка на него) и вызовет GetMessage, который в конечном итоге выполнит операцию с компонентом, которая не будет работать, потому что компонент действительно был disposed.

Что вы должны сделать, так это убедиться, что вы освободили все ресурсы при удалении компонента. Вы можете сделать это , реализовав IDisposable с вашим компонентом. Обычно это будет выглядеть так:

@implements IDisposable

@code {
     private Timer _timer;

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

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

Поскольку ваш компонент наследуется от OwningComponentBase, который уже реализует сам IDisposable, вам нужно будет расширить удаление вашего компонента:

@inherits OwningComponentBase<TestBlazor.Client.APIGateway>

@code {
     private Timer _timer;

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

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