I made a simple system to add and delete file from an EF Core database like this :
Add a file :
public async Task AddFile(IFileListEntry file) { File fileToAdd = await File.GetFileAsync(file); _context.Files.Add(fileToAdd); _context.SaveChanges(); }
Get the file from an IFileListEntry
interface, containing the file into a Stream
:
public static async Task<File> GetFileAsync(IFileListEntry file) { using MemoryStream ms = new MemoryStream(); await file.Data.CopyToAsync(ms); File f = new File { Name = file.Name, Type = file.Type, Size = file.Size, LastModified = file.LastModified, Data = ms.ToArray(), }; ms.Dispose(); return f; }
Remove a file :
public void DeleteFile(File file) { file.Data = new byte[0]; //Test _context.Files.Remove(file); _context.SaveChanges(); }
All the files added are stored into a List
, and deleted from it, and the list itself is contained into .razor
file (not shown here as I think it's irrelavant to my problem), and also in an EF Core database.
The database context _context
is obtained through depedency injection and inherits from DbContext
class.
So my problem is : after adding and deleting a file, I can observe a memory leak as the RAM is at the same level after the addition of the file into the database and the list.
So what I'm doing wrong ? I really can't understand where it could possibly come from, as the MemoryStream
is disposed after its use, and when the file is deleted, I replace the filled byte[]
by an empty one, or even a null
reference. I made sure the List
in my .razor
file is a new empty list that we fill up again with the files added. I didn't test for the _context
though.
I think that your DI container does not dispose the dbcontext.
Check the dbcontext documentation here
The lifetime of the context begins when the instance is created and ends when the instance is either disposed or garbage-collected. Use using if you want all the resources that the context controls to be disposed at the end of the block. When you use using, the compiler automatically creates a try/finally block and calls dispose in the finally block.
public void UseProducts()
{
using (var context = new ProductContext())
{
// Perform data access using the context
}
}
If the context instance is created by a dependency injection container, it is usually the responsibility of the container to dispose the context.
So if your DI does not dispose the context, then it remains in memory and thus, it looks like you have a leak.
Another thing that may occur, is that the Garbage Collection does not occur predictably check garbage collection here . So it might take some time to see the freed memory.
One last thing: You don't need to ms.Dispose();
MemoryStream
This type implements the IDisposable interface, but does not actually have any resources to dispose. This means that disposing it by directly calling Dispose() or by using a language construct such as using (in C#) or Using (in Visual Basic) is not necessary.
So the MemoryStream
would not be the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.