以下代码不起作用(抛出“reader.NextResult()上的致命错误”)
我的目标是执行批处理选择,然后通过批量复制异步插入每个结果集的数据。
我认为问题在于,在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();发布于 2014-09-15 19:41:17
是的,你没有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) )
发布于 2014-09-15 19:41:26
是。您必须延迟NextResult,直到您确定WriteToServerAsync已完成其工作。正确执行此操作的最简单方法是将包含方法设置为async方法,并将其转换为await WriteToServerAsync,如下所示:
await bulkCopy.WriteToServerAsync(reader);有关async和await的更多信息,请参阅async/await tutorials like this one from dotnetperls和/或Microsoft's own documentation。
https://stackoverflow.com/questions/25847162
复制相似问题