在 Blazor 中使用 Base64 图像时如何避免内存泄漏

问题描述 投票:0回答:1

我正在使用 .NET 8 的官方版本来开发 Blazor MAUI 混合应用程序。
我有一个功能,用户可以选择图像并将其显示给用户。我正在使用 Base64,但我注意到内存泄漏。这是我的代码:

@page "/memory_leak"
@using System.Diagnostics

<MudStack Class="ma-4" AlignItems="AlignItems.Center">
    <MudPaper Class="pa-3" Elevation="3">
        @if (_imageBase64 is null)
        {
            <MudAlert Severity="Severity.Normal">Choose an Image</MudAlert>
        }
        else
        {
            <MudImage Height="400" Alt="pic" Class="rounded-lg" 
                      Src="@string.Concat("data:image/png;base64,", _imageBase64)" 
                      />
        }
    </MudPaper>
    <MudFileUpload T="IBrowserFile" FilesChanged="UploadFiles" Class="pa-3">
            <ButtonTemplate>
                <MudFab
                    Size="Size.Small"
                    HtmlTag="label"
                        Color="Color.Secondary"
                        Icon="@Icons.Material.Filled.Image"
                        Label="Load picture"
                        for="@context" />
            </ButtonTemplate>
        </MudFileUpload>
    <MudPaper Class="pa-3">Item 3</MudPaper>
</MudStack>

@code
{
    private string? _imageBase64;

    private async Task UploadFiles(IBrowserFile file)
    {
        Debug.WriteLine($"size:{file.Size}");
        await using var openReadStream = file.OpenReadStream(file.Size);
        byte[] buffer = new byte[file.Size];
        var readAsync = await openReadStream.ReadAsync(buffer);
        _imageBase64 = Convert.ToBase64String(buffer, 0, readAsync);
    }
}

每当我上传图像时,内存都会增加,并且垃圾收集器(GC)不会回收多余的内存。这一直持续到页面最终崩溃

我正在尝试消除其他可能的原因,我发现当我注释掉

Src="@string.Concat("data:image/png;base64,", _imageBase64)"
时,内存泄漏不再发生。这表明图像显示导致了内存泄漏。

为了排除与MudBlazor相关的问题,我直接使用HTML标签,但仍然出现内存泄漏:

           @*  <MudImage Height="400" Alt="pic" Class="rounded-lg" 
                      Src="@string.Concat("data:image/png;base64,", _imageBase64)" 
            /> *@

            <img src="@string.Concat("data:image/png;base64,", _imageBase64)" class="rounded-lg" height="400px"/>

最后,我通过使用 JavaScript 对象 URL 解决了这个问题。

但是,我仍然很好奇这个内存泄漏是如何发生的。我想知道我的使用是否存在问题,或者 Blazor 是否存在潜在的错误。我搜索了类似的问题,但找不到其他人遇到同样的问题。

c# .net memory-leaks blazor maui
1个回答
0
投票

这可以参考文档:ASP.NET Core Blazor 文件上传

在以下示例中,

browserFile
代表上传的文件并实现
IBrowserFile
。本文后面的文件上传组件中显示了
IBrowserFile
的工作实现。

❌不支持:不建议使用以下方法,因为文件的 Stream 内容被读入内存中的字符串(读取器):

var reader = 
    await new StreamReader(browserFile.OpenReadStream()).ReadToEndAsync();

❌不支持:不建议将以下方法用于 Microsoft Azure Blob 存储,因为在调用 UploadBlobAsync 之前,文件的 Stream 内容会复制到内存中的 MemoryStream (memoryStream) 中:

var memoryStream = new MemoryStream();
browserFile.OpenReadStream().CopyToAsync(memoryStream);
await blobContainerClient.UploadBlobAsync(
    trustedFileName, memoryStream));

✔️支持:建议使用以下方法,因为文件的 Stream 是直接提供给消费者的,即在提供的路径创建文件的 FileStream:

await using FileStream fs = new(path, FileMode.Create);
await browserFile.OpenReadStream().CopyToAsync(fs);

✔️支持:对于 Microsoft Azure Blob 存储,建议使用以下方法,因为文件的 Stream 直接提供给 UploadBlobAsync:

await blobContainerClient.UploadBlobAsync(
    trustedFileName, browserFile.OpenReadStream());
© www.soinside.com 2019 - 2024. All rights reserved.