Why doesn't SaveChangesAsync save all my changes?
I think that maybe I am missing something in my understanding of how this should work. I have some code that is importing a file. It iterates over each record, does some processing, and then adds that record to the table via an instance DbContext
.
I am initializing DbContext
like this:
protected void ResetDbContext()
{
if (_db != null)
_db.Dispose();
_db = new AppDBEntities();
_db.Configuration.AutoDetectChangesEnabled = false;
_db.Configuration.ValidateOnSaveEnabled = false;
}
My main loop looks something like this:
foreach (var rec in engine)
{
var record = new CommonImportRecord(rec);
ProcessRecord(record, options, index);
index++;
}
_db.SaveChanges();
ProcessRecord
looks something like this:
protected async Task<int> ProcessRecord(CommonImportRecord record, ImportOptions options, int index)
{
DisplayProcessStatus(index, options);
// Code removed which fills in various properties of the record
_db.MyTable.Add(record);
if (index % options.UpdateInterval == 0)
{
return await _db.SaveChangesAsync();
// This was originally here, commented out when I changed SaveChanges() to SaveChangesAsync()
// ResetDBContext();
}
}
The only real change I made for SaveChangesAsync()
was to add async Task<int>
as the return type ProcessRecord
by changing SaveChanges()
to return await SaveChangesAsync()
and commenting out the callResetDBContext.
Things worked as expected prior to the asynchronous changes. Subsequently, it seems that all my notes are not saved.
What am I missing here?
source to share
You call a method async
that returns a task without waiting for it to complete. To move to the next record, you must use await
for asynchronously . It is also the standard to name your methods async
with the "Async" suffix:
foreach (var rec in engine)
{
var record = new CommonImportRecord(rec);
var result = await ProcessRecordAsync(record, options, index);
index++;
}
source to share
To add to @ l3arnon's answer, you can save yourself creating a state machine internally ProcessRecordAsync
:
It:
protected async Task<int> ProcessRecordAsync(CommonImportRecord record, ImportOptions options, int index)
{
// Removed code for brevity
return await _db.SaveChangesAsync();
}
You can enable:
protected Task<int> ProcessRecordAsync(CommonImportRecord record, ImportOptions options, int index)
{
// Removed code for brevity
return _db.SaveChangesAsync();
}
Since you don't really use the return value SaveChangesAsync
inside the call ProcessRecordAsync
.
source to share