简体   繁体   English

Blazor:使用 InvokeAsync 更新导致 memory 泄漏

[英]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.

相关问题 在 blazor 中使用 EventCallback 时,我应该将什么传递给 InvokeAsync? - What should I pass to InvokeAsync when using EventCallback in blazor? 在 Blazor 中使用 js.InvokeAsync 后查看未更新 - View not updating after using js.InvokeAsync in Blazor Blazor 中的 StateHasChanged() 与 InvokeAsync(StateHasChanged) - StateHasChanged() vs InvokeAsync(StateHasChanged) in Blazor 单例可能的内存泄漏 blazor 组件 - Singleton possible memory leak blazor component 在 BlazorStrap Carousel 上使用 JSRuntime.InvokeAsync 会导致“索引超出范围”错误 - Using JSRuntime.InvokeAsync causes "Index was out of range" error on BlazorStrap Carousel 为什么“InvokeAsync”在 Blazor 组件中显示为错误? - Why does 'InvokeAsync' show as an error in a Blazor component? Blazor InvokeAsync 在页面重新加载后不再工作 - Blazor InvokeAsync no longer working after page reload Blazor [参数] 未使用@ref 更新 - Blazor [Parameter] not update using @ref Blazor 异常 - 当前线程未与 Dispatcher 关联。 使用 InvokeAsync() - Blazor exception - The current thread is not associated with the Dispatcher. Use InvokeAsync() Blazor 与 MatBlazor 在 AuthorizeView 中使用 MatTableRow 导致相同的参数名称错误 - Blazor with MatBlazor using MatTableRow in AuthorizeView causes same parameter name error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM