【问题标题】:How to call particular function after every two mins In Blazor razor component?如何在 Blazor razor 组件中每两分钟调用一次特定函数?
【发布时间】:2020-05-05 09:32:10
【问题描述】:

我想在 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 组件名称。如果有人能告诉我我到底做错了什么会很有帮助?或者还有其他解决方案吗?

【问题讨论】:

    标签: c# asp.net-core blazor


    【解决方案1】:

    问题在于,即使组件已从视图中移除,您的计时器仍会继续运行。在这种情况下,计时器只会尝试访问组件实例(因为它仍然有对它的引用),并调用GetMessage,这最终将对组件进行操作,因为组件实际上已经处置。

    您应该确保在移除组件时释放所有资源。你可以用你的组件做到这一点by implementing 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();
         }
    }
    

    【讨论】:

    • 嗨,Poke,我将计时器变量放在全局范围内,并在 OnInitializedAsync 中调用了 SetTimer()。在此之后,我调用了 Dispose 函数,所以它可以工作了。谢谢
    • 这保存了一个重要的项目。即使在我离开页面后,烦人的计时器也不会停止滴答作响,而且我没有找到并尝试过任何解决方法似乎有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2010-11-16
    • 2017-11-15
    • 2018-01-17
    • 2016-07-08
    • 1970-01-01
    相关资源
    最近更新 更多