[英]Blazor: Update using InvokeAsync causes memory leak
I have a Blazor app with a list that I want to update automatically using a Timer every X seconds.我有一个 Blazor 应用程序,其中包含我想每 X 秒使用计时器自动更新的列表。 When I run the app using the following code, the list is refreshed every 10 seconds, but the memory usage rises on every refresh.
当我使用以下代码运行应用程序时,列表每 10 秒刷新一次,但每次刷新时 memory 的使用率都会上升。 The memory usage of the app starts at 2-300 MB and rises past 1 GB within 10 refreshes.
该应用程序的 memory 使用量从 2-300 MB 开始,并在 10 次刷新内超过 1 GB。
I was hoping that my code would overwrite the existing list on every refresh, thus not using more and more memory.我希望我的代码在每次刷新时都会覆盖现有列表,因此不会使用越来越多的 memory。 What am I missing?
我错过了什么? Could it be because the refreshing is done in multiple threads?
难道是因为刷新是在多个线程中完成的?
public partial class MyBlazorComponent
{
private Dictionary<Guid, IList<MyModel>> MyList { get; set; }
private Timer Timer { get; set; }
// A simple lock to make sure that multiple refreshes don't overlap
private bool _isRefreshing;
protected override async Task OnInitializedAsync()
{
await UpdateMyList(); // the initial loading of the list
await base.OnInitializedAsync();
Timer = new Timer(async _ =>
{
await RefreshList();
}, null, 0, 10000);
}
private async Task UpdateMyList()
{
_isRefreshing = true;
MyList = null;
MyList = await _myService.GetList(); // external service to get list contents
_isRefreshing = false;
}
private async Task RefreshList()
{
if (!_isRefreshing)
{
// Without these two lines, the list won't update
MyList = null;
await InvokeAsync(StateHasChanged);
// Update the list
await UpdateMyList();
await InvokeAsync(StateHasChanged);
}
}
}
It seems the issue here is not in the code provided, but the statement _myService.GetList().这里的问题似乎不在提供的代码中,而是在语句 _myService.GetList() 中。 As @HenkHolterman has keenly observed, the only memory-leak in this code is that the timer is not disposed of when the component is no longer in use.
正如@HenkHolterman 敏锐地观察到的那样,此代码中唯一的内存泄漏是当组件不再使用时计时器没有被释放。 This can be done like:
这可以像这样完成:
public partial class MyBlazorComponent : IDisposable
{
private Timer Timer { get; set; }
//other code.....
public void Dispose()
{
Timer?.Dispose();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.