以下代码不起作用(在 reader.NextResult() 上抛出“ fatal error ”)
我的目标是执行批量选择,然后通过批量复制异步插入每个结果集的数据。
我认为问题在于,在 reader.NextResult()
上,当前结果集从内存中释放,但由于异步批量操作正在使用它,因此它会引发 fatal error (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();
最佳答案
是的,您没有等待
结果;你进步太快了。应该是:
await bulkCopy.WriteToServerAsync(reader);
或
await bulkCopy.WriteToServerAsync(reader).ConfigureAwait(false);
还要注意,Task.WaitAll()
没有做任何有用的事情;你是说“现在等待所有零个任务完成”。
另请注意,如果您要采用异步
,那么您最好始终采用异步
:
var reader = await selectCmd.ExecuteReaderAsync();
...
await bulkCopy.WriteToServerAsync(reader);
...
await reader.NextResultAsync();
(同样,如果需要的话,也许每个都带有 .ConfigureAwait(false)
)
关于.net - 异步 SQL 批量复制和批量选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25847162/