You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor上传300MB文件时OpenReadStream内存占用过高且无法释放

问题分析

当前代码直接将300MB文件一次性读入byte[],在Blazor WebAssembly环境下会触发双重内存分配:一是.NET侧的byte[]占用,二是浏览器JS runtime处理文件流时的额外内存开销,两者叠加导致内存暴增。另外,.NET 6.0.101版本的Blazor WASM在IBrowserFile流处理上存在内存泄漏BUG,即使手动调用GC.Collect()也无法释放JS侧残留的内存。

解决方案

1. 采用流式上传,避免一次性加载整个文件到内存

不要将文件全部读入byte[],直接将IBrowserFile的流传入MultipartFormDataContent,通过分块传输减少内存占用:

private async Task<bool> UploadFile(IReadOnlyCollection<IBrowserFile> imgFiles)
{
    filesComponent.clearDragClass();
    using var multipartContent = new MultipartFormDataContent();

    foreach (var imgFile in imgFiles)
    {
        var streamContent = new StreamContent(imgFile.OpenReadStream(1000000000));
        streamContent.Headers.ContentType = new MediaTypeHeaderValue(imgFile.ContentType);
        multipartContent.Add(streamContent, "uploadedFiles", imgFile.Name);
    }

    // 发送上传请求
    using var httpClient = new HttpClient();
    var response = await httpClient.PostAsync("你的服务器上传接口地址", multipartContent);
    return response.IsSuccessStatusCode;
}

这种方式只会保留当前传输块的内存占用,不会一次性加载整个300MB文件。

2. 升级.NET版本至6.0.105及以上

.NET 6.0.101存在Blazor WASM文件流处理的内存泄漏问题,微软在后续补丁版本中已修复该BUG。升级到最新的.NET 6补丁版本(或直接升级至.NET 7/8),可解决上传后内存无法释放的问题。

3. 手动释放JS侧资源(临时兼容方案)

如果暂时无法升级.NET版本,可通过JS互操作强制释放浏览器侧的文件引用:
首先在wwwroot/index.html中添加JS函数:

window.releaseFileReference = function(fileRef) {
    if (fileRef) {
        URL.revokeObjectURL(fileRef);
    }
};

然后在C#上传完成后调用该函数:

// 上传完成后遍历文件释放JS侧资源
foreach (var imgFile in imgFiles)
{
    await JS.InvokeVoidAsync("releaseFileReference", imgFile.Reference);
}
关键注意事项
  • Blazor WASM环境下,处理大文件必须优先采用流式方案,避免一次性加载文件到内存。
  • 及时释放不再使用的流对象和JS侧引用,降低内存泄漏风险。

内容的提问来源于stack exchange,提问作者Elnur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:45:29