Reputation: 29
I'm working on a project where users can queue up actions to happen in the future. Each future action is saved in the database. I'm trying to find a way to get all the actions that have already passed and act on them. Currently I'm doing this:
public class TaskingManager
{
private static readonly System.Timers.Timer RefreshEventsLoop = new(1000);
public void Initialize()
{
RefreshEventsLoop.Elapsed += RefreshEventsLoop_Elapsed;
RefreshEventsLoop.AutoReset = false;
RefreshEventsLoop.Start();
}
private void RefreshEventsLoop_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{
RefreshEventsLoop.Enabled = false;
ProcessEventsQueue();
RefreshEventsLoop.Enabled = true;
}
private void ProcessEventsQueue()
{
var timeNow = DateTime.UtcNow;
var context = new GalaxyDbContext(_dbOptions);
var dbFunctions = new DatabaseFunctions(context);
var eventsToProcess = context.FutureEvents
.Where(futureEvent => futureEvent.TriggerTime <= timeNow)
.ToList();
if (eventsToProcess.Any())
{
context.FutureEvents.RemoveRange(eventsToProcess);
context.SaveChanges();
foreach (var pastEvent in eventsToProcess)
{
_messageMap[pastEvent.MessageType].Invoke(dbFunctions).Execute(pastEvent);
}
}
else
{
dbFunctions.CreateFutureScienceTask();
}
}
}
This seems to work ok. But the problem is that after the app has been running for a while, I can see the LINQ part is taking up a huge amount of memory: 524MB used
And if I leave it running for a few days then it's up in the gigs.
I'm guessing running this query every second is wasteful on resources. But I don't know of a better way to do this. Is there a way to continuously check the database for something like this?
Upvotes: 0
Views: 435
Reputation: 673
The first thing i can see is that you are not disposing the databasecontextt afer you used it. Read this for more info about entityframework context lifetime.
To properly dispose it use a using statement.
using (var context = new GalaxyDbContext(_dbOptions))
{
//your code that uses the context
}
Or with new using syntax:
using (var context = new GalaxyDbContext(_dbOptions));
//your code that uses the context
Right know the problem could be that you create a context everytime you call the function and never dispose it and it still keeps references to the data etc..
Upvotes: 2