为什么SaveChangesAsync实际上没有保存我的所有更改?

时间:2014-09-23 14:02:11

标签: c# .net task-parallel-library async-await entity-framework-6

我想我可能会错过一些关于这应该如何工作的东西。我有一些导入文件的代码。它循环遍历每条记录,进行一些处理,然后通过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.

在异步更改之前,事情按预期工作。之后,我的所有记录都没有被保存。

我在这里缺少什么?

2 个答案:

答案 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的返回值。