我有一块代码,想要对commands
可枚举对象中的每个命令都应用using
语句。请问C#中的语法是什么?
await using var transaction = await conn.BeginTransactionAsync(cancel);
IEnumerable<DbCommand> commands = BuildSnowflakeCommands(conn, tenantId);
var commandTasks = new List<Task>();
foreach (var command in commands)
{
command.CommandTimeout = commandTimeout;
command.Transaction = transaction;
commandTasks.Add(command.ExecuteNonQueryAsync(cancel));
}
try
{
await Task.WhenAll(commandTasks);
}
catch (SnowflakeDbException)
{
await transaction.RollbackAsync(cancel);
return;
}
await transaction.CommitAsync(cancel);
编辑:Rider/ReSharper似乎认为这两个语句是等价的,或者至少我会得到一个提示将for
转换为foreach
(这显然是错误的):
for (var i = 0; i < commands.Count; i++)
{
await using var command = commands[i];
command.CommandTimeout = commandTimeout;
command.Transaction = transaction;
commandTasks.Add(command.ExecuteNonQueryAsync(cancel));
}
并且
foreach (var command in commands)
{
command.CommandTimeout = commandTimeout;
command.Transaction = transaction;
commandTasks.Add(command.ExecuteNonQueryAsync(cancel));
}
编辑2:经过一些讨论和一些有用的回答,这是我要采用的方案:
var transaction = await conn.BeginTransactionAsync(cancel);
var commands = BuildSnowflakeCommands(conn, tenantId);
var commandTasks = commands.Select(async command =>
{
await using (command)
{
command.CommandTimeout = commandTimeout;
command.Transaction = transaction;
await command.ExecuteNonQueryAsync(cancel);
}
});
try
{
await Task.WhenAll(commandTasks);
await transaction.CommitAsync(cancel);
}
catch (SnowflakeDbException)
{
await transaction.RollbackAsync(cancel);
}
finally
{
await transaction.DisposeAsync();
}
await
被触发时,async
lambda 将立即返回一个Task
,允许每个命令并行执行。每个命令只有在ExecuteNonQueryAsync
完成后才会被处理。 - Johnathan Barclaytransaction
现在在外部作用域中被释放了。 - xandermonkey