【发布时间】:2021-03-14 14:45:45
【问题描述】:
我有一个 Blazor 应用程序,其中有一个列表,我想使用计时器每隔 X 秒自动更新一次。当我使用以下代码运行应用程序时,列表每 10 秒刷新一次,但每次刷新时内存使用量都会增加。应用程序的内存使用量从 2-300 MB 开始,并在 10 次刷新内超过 1 GB。
我希望我的代码在每次刷新时都会覆盖现有列表,从而不会使用越来越多的内存。我错过了什么?难道是因为刷新是在多个线程中完成的?
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);
}
}
}
【问题讨论】:
-
我制作了您共享的代码的一个小版本 (blazorfiddle.com/s/sr0spgs8),但我没有遇到您所描述的问题。当我在本地运行它时,我也没有注意到内存泄漏。还有一点需要特别注意的是,我不需要调用两次 StateHasChanged 来更改列表。您能否分享一些剃须刀代码以及有关服务的更多详细信息?对我来说,问题似乎不在您提供的代码中。
-
你为什么用
StateHasChanged,更不用说InvokeAsync(StateHasChanged)?替换列表将导致仅重绘受影响的元素。StateHasChanged将触发整个页面的更新。InvokeAsync.... 这有什么意义?您是否尝试过在计时器中简单地调用UpdateMyList? -
顺便说一句,您使用的是哪个 Blazor 版本?服务器端还是 Web 程序集? 旧需要 Blazor 版本
StateHasChanged,.NET 5 不需要 -
旁注,您正在泄漏计时器,但这不会导致您看到的内存使用。
-
完全忽略了@HenkHolterman。这确实应该实现 IDispose 以摆脱不再使用的计时器。
标签: blazor