-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Describe the bug
The new cool Blazor Webassembly JS to .NET streaming (#33986) provided via the BrowserFileStream as returned from IBrowserFile.OpenReadStream() does not dispose the underlying/supporting JSStreamReference leaving the unmanaged blobs intact on the JS side consuming memory (which could be quite a bit, especially if doing many image resizes).
Looking at the code, it does seem that it might get GC'd at some point. But not even calling GC.Collect() disposes the JSStreamReference.
Preferred behavior
That the JSStreamReference was disposed when the stream has been read to the end, but also when disposing the BrowserFileStream (to cover for if it was not read till the end).
To Reproduce
Using below sample code (extracted from E2E BasicTestApp):
- Upload a few images,
- Navigate away, do GC etc..
- Open DevTools and take a Memory Heap Snapshot.
- Inspect snapshot and apply Class Filter: "Blob"
- Find list of blobs with increasing count for every image upload.
<InputFile OnChange="LoadImage" id="input-image" />
@code {
long maxFileSize = 1024 * 1024 * 15;
string? imageDataUri;
async Task LoadImage(InputFileChangeEventArgs e)
{
var format = "image/jpeg";
var imageFile = await e.File.RequestImageFileAsync(format, 640, 480);
using var browserFileStream = imageFile.OpenReadStream(maxFileSize);
using var memoryStream = new MemoryStream();
await browserFileStream.CopyToAsync(memoryStream);
imageDataUri = $"data:{format};base64,{Convert.ToBase64String(memoryStream.ToArray())}";
}
}although this sample uses the image resizer the issue also exist when just opening the file stream directly
PR
I've been looking into this for quite some time now, and I am willing to submit a PR after discussing a few of my ideas.
Further technical details
- ASP.NET 6.0.0-preview.7