3

我想我可能會錯過某些東西,理解它應該如何工作。我有一些導入文件的代碼。它遍歷每條記錄,進行一些處理,然後通過DbContext實例將該記錄添加到表中。爲什麼SaveChangesAsync實際上不保存所有更改?

我初始化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.

事情都按預期之前異步更改。之後,似乎沒有保存所有記錄。

我在這裏錯過了什麼?

回答

9

您正在調用一個async方法,該方法返回一個任務而不用等待它完成。您需要異步使用await才能繼續前進到下一條記錄。這也是一個標準來命名async方法的「異步」後綴:

foreach (var rec in engine) 
{ 
    var record = new CommonImportRecord(rec); 
    var result = await ProcessRecordAsync(record, options, index); 
    index++; 
} 
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(); 
} 

由於您在調用ProcessRecordAsync時沒有真正使用SaveChangesAsync的返回值。

相關問題