我想我可能会错过一些关于这应该如何工作的东西。我有一些导入文件的代码。它循环遍历每条记录,进行一些处理,然后通过DbContext
实例将该记录添加到表中。
我像这样初始化DbContext
:
protected void ResetDbContext()
{
if (_db != null)
_db.Dispose();
_db = new AppDBEntities();
_db.Configuration.AutoDetectChangesEnabled = false;
_db.Configuration.ValidateOnSaveEnabled = false;
}
我的主循环看起来像这样:
foreach (var rec in engine)
{
var record = new CommonImportRecord(rec);
ProcessRecord(record, options, index);
index++;
}
_db.SaveChanges();
ProcessRecord
看起来像这样:
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();
}
}
我为SaveChangesAsync()
所做的唯一真正的更改是添加async Task<int>
作为ProcessRecord
的返回类型,将SaveChanges()
更改为return await SaveChangesAsync()
并注释掉致电ResetDBContext.
在异步更改之前,事情按预期工作。之后,我的所有记录都没有被保存。
我在这里缺少什么?
答案 0 :(得分:10)
您正在调用async
方法,该方法返回任务而无需等待它完成。在转到下一条记录之前,您需要使用await
异步等待。它也是使用&#34; Async&#34;命名async
方法的标准。后缀:
foreach (var rec in engine)
{
var record = new CommonImportRecord(rec);
var result = await ProcessRecordAsync(record, options, index);
index++;
}
答案 1 :(得分:2)
要添加@ l3arnon的答案,您可以自己在ProcessRecordAsync
内自行生成状态机:
此:
protected async Task<int> ProcessRecordAsync(CommonImportRecord record, ImportOptions options, int index)
{
// Removed code for brevity
return await _db.SaveChangesAsync();
}
可以变成:
protected Task<int> ProcessRecordAsync(CommonImportRecord record, ImportOptions options, int index)
{
// Removed code for brevity
return _db.SaveChangesAsync();
}
由于您在SaveChangesAsync
的调用中没有真正使用ProcessRecordAsync
的返回值。