以下代码无法正常工作(抛出#34;致读者的致命错误.NextResult()")
我的目标是执行批量选择,然后通过批量复制插入每个结果集async的数据。
我认为问题在于reader.NextResult()
当前结果集是从内存中释放的,但由于异步批量操作正在使用它,因此会抛出致命错误(InvalidOperationException)。有什么想法吗?
var sqlQuery = new DbExtensions.SqlBuilder();
foreach (var table in tableBatch)
{
sqlQuery
.SELECT("*")
.FROM("[" + table.TableName + "]");
}
var selectCmd = sqlQuery.ToCommand(clientDb);
logger.Info("Executing select", batchSelectSize);
var reader = selectCmd.ExecuteReader();
var i = 0;
while (reader.HasRows)
{
logger.Info("Bulk insert");
var table = tableBatch.ElementAt(i);
var bulkCopy = new SqlBulkCopy(serverDb, SqlBulkCopyOptions.Default, tx);
bulkCopy.DestinationTableName = String.Format("[{0}]", table.TableName);
bulkCopy.EnableStreaming = table.EnableStreaming;
bulkCopy.WriteToServerAsync(reader);
i++;
reader.NextResult(); // fatal error occures (sometimes)
}
logger.Info("Waiting for bulk operations to complete");
Task.WaitAll();
logger.Info("Committing transaction");
tx.Commit();
答案 0 :(得分:2)
是的,你没有await
结果;你过早地前进了。那应该是:
await bulkCopy.WriteToServerAsync(reader);
或
await bulkCopy.WriteToServerAsync(reader).ConfigureAwait(false);
另请注意Task.WaitAll()
没有任何用处;你说"现在等待完成这些任务的所有零"。
另请注意,如果您要async
,那么您可以在async
进行整个过程:
var reader = await selectCmd.ExecuteReaderAsync();
...
await bulkCopy.WriteToServerAsync(reader);
...
await reader.NextResultAsync();
(如果需要的话,也许每个都有.ConfigureAwait(false)
)
答案 1 :(得分:1)
是。您必须推迟NextResult
,直到您确定WriteToServerAsync
已完成其工作为止。正确执行此操作的最简单方法是使包含方法成为async
方法,并await
WriteToServerAsync
,如下所示:
await bulkCopy.WriteToServerAsync(reader);
有关async
和await
的详情,请参阅async/await tutorials like this one from dotnetperls和/或Microsoft's own documentation。