2

In my ASP.NET MVC action method to process uploaded files, I have

[HttpPost]
public async Task<ActionResult> UploadFiles(IEnumerable<IFormFile> files)
...
    foreach (var file in files)
    {
        await using var stream = file.OpenReadStream();
...

Normal processing should mean that every file's stream is disposed (as per the using). But what happens if there is an exit from the loop before all files are processed - will ASP.NET dispose of all the other streams?

DennisR
  • 127
  • 2
  • 7

3 Answers3

0

ASP.NET manages the lifetime of whatever resources are used by IFormFile, not you. The only thing you have to worry about disposing is whatever OpenReadStream() returns, and that's taken care of by the using in your sample code. If your method throws an exception, then the runtime will clean that up for you.

In general, if something isn't disposable, don't think about it.

Etienne de Martel
  • 34,692
  • 8
  • 91
  • 111
  • Thank you. As a follow-up question, let's say – DennisR Apr 24 '23 at 14:29
  • Thank you. If a helper method creates the collection of IFormFiles (write to MemoryStream / new FormFile(stream,...), and the loop was exited before all were processed. Would I then have to do Dispose? I'd think so, but IFormFile doesn't have Dispose. Would I need to do have a try/finally and loop through doing "using var stream = file.OpenReadStream()"? It seems odd, and some may have been 'processed' (disposed), and I don't think there's a way to detect already disposed. I expect that premature 'exit loop' should be very rare; should I not be concerned and the GC will eventually clean up? – DennisR Apr 24 '23 at 14:44
  • If something is disposable then you should dispose it before it goes out of scope. If you have temporary files on disk and want to clean them up afterwards you should do so when necessary. But really the responsibility for cleanup falls on whoever _created_ those form file objects, not whoever is using them. – Etienne de Martel Apr 24 '23 at 23:10
0

ASP.NET supports uploading one or more files using buffered model binding for smaller files and unbuffered streaming for larger files.

The disk and memory used by file uploads depend on the number and size of concurrent file uploads. If an app attempts to buffer too many uploads, the site crashes when it runs out of memory or disk space.

Any single buffered file exceeding 64 KB is moved from memory to a temp file on disk.

Temporary files for larger requests are written to the location named in the ASPNETCORE_TEMP environment variable. If ASPNETCORE_TEMP is not defined, the files are written to the current user's temporary folder.

So it depends on the number and file sizes, if they are buffered in the memory they will clean after the request is finished (something like request scoped) if they are saved into a temp path then they will be removed by OS.

For more detail check this link: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-7.0

sa-es-ir
  • 3,722
  • 2
  • 13
  • 31
-1

Sure GarbageCollector will take care of it. It's good to manually dispose it, but GarbageCollector is able to detect those variables which are not usable anymore. GarbageCollector runs periodically, you can run it manually but it doesn't occurs right after the loop, it happens at it's period.

see this question: Is a memory leak created if a MemoryStream in .NET is not closed?

RezaNoei
  • 1,266
  • 1
  • 8
  • 24
  • That is true for `MemoryStream`, but not streams that hold unmanaged resources, like `FileStream`. But this is irrelevant here: `IFormFile` is not a stream. – Etienne de Martel Apr 22 '23 at 00:43