【发布时间】:2021-06-10 20:05:51
【问题描述】:
我在 AWS Lambda 中有一个方法,它接收完整的项目列表。它处理这些项目,然后将它们插入到 Dynamo DB 表中。处理或插入数据库的顺序无关紧要。
我正在寻找最线程安全且易于理解的方式来加快运行速度;通过使用async await 或其他(可能是并行的?)操作。
我在想Parallel.ForEach(),但这似乎有点沉重。有没有更简单、更明显的方法?
private async Task<int> LoadAutocomplete(IList<Item> resp)
{
var client = new AmazonDynamoDBClient();
foreach (var item in resp)
{
var request = new PutItemRequest
{
TableName = EnvironmentHelper.DynamoTableName,
Item = new Dictionary<string, AttributeValue>()
{
{ "LANGUAGE", new AttributeValue { S = item.LANGUAGE }},
{ "COUNTRY", new AttributeValue { S = item.COUNTRY }}
}
};
await client.PutItemAsync(request);
System.Threading.Thread.Sleep(100);
}
}
选项 1
private async Task<int> LoadAutocomplete(IList<Item> resp)
{
var client = new AmazonDynamoDBClient();
Parallel.ForEach(resp, async item =>
{
var request = new PutItemRequest
{
TableName = EnvironmentHelper.DynamoTableName,
Item = new Dictionary<string, AttributeValue>()
{
{ "LANGUAGE", new AttributeValue { S = item.LANGUAGE }},
{ "COUNTRY", new AttributeValue { S = item.COUNTRY }}
}
};
await client.PutItemAsync(request);
}
}
选项 2 导致编译器抱怨 LoadAutoComplete 方法“缺少等待操作符并且将同步运行”。
选项 2 正如@jamesfaix 建议的那样
private async Task<int> LoadAutocomplete(IList<Item> resp)
{
var client = new AmazonDynamoDBClient();
var tasks = items.Select(x => DoSomethingAsync(client, x)).ToList();
await Task.WhenAll(tasks);
}
private DoSomething(AmazonDynamoDBClient client, Item item)
{
var request = new PutItemRequest
{
TableName = EnvironmentHelper.DynamoTableName,
Item = new Dictionary<string, AttributeValue>()
{
{ "LANGUAGE", new AttributeValue { S = item.LANGUAGE }},
{ "COUNTRY", new AttributeValue { S = item.COUNTRY }}
}
};
await client.PutItemAsync(request);
}
选项 + @martin 建议
"Use Parallel.For in batches in dotnet core" 帖子确实回答了我的问题,但我选择了@jamesfaix 发布的the answer,因为它大大改进了我的代码。
【问题讨论】:
-
不要在异步代码中使用
Sleep。使用await Task.Delay -
啊,是的。我实际上已经删除了那条线,但忘记了。无论如何,我可能会被它搞砸,因为我似乎记得需要该行来确保数据库插入正常执行。
-
在您的选项 1 和选项 2 之间,我会更关心行为差异而不是句法清洁度。
-
您可以直接拒绝“选项 1”。
Parallel.ForEachis not async friendly. -
您在a comment 中提到“数据库插入正常执行”,在操作之间添加了 100 毫秒的延迟。
标签: c# .net-core foreach async-await