Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 此foreach的最干净异步版本?_C#_.net Core_Foreach_Async Await - Fatal编程技术网

C# 此foreach的最干净异步版本?

C# 此foreach的最干净异步版本?,c#,.net-core,foreach,async-await,C#,.net Core,Foreach,Async Await,我在AWS Lambda中有一个方法,它接收完整的项目列表。它处理这些项,然后将它们插入到Dynamo DB表中。处理或插入数据库的顺序无关紧要 我正在寻找最安全的线程,但易于理解的方式,使它运行得更快;通过使用异步等待或其他(可能是并行的?)操作 我在想Parallel.ForEach(),但这似乎有点沉重。有没有更简单、更明显的方法 private async Task<int> LoadAutocomplete(IList<Item> resp) { var

我在AWS Lambda中有一个方法,它接收完整的项目列表。它处理这些项,然后将它们插入到Dynamo DB表中。处理或插入数据库的顺序无关紧要

我正在寻找最安全的线程,但易于理解的方式,使它运行得更快;通过使用
异步等待
或其他(可能是并行的?)操作

我在想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);
    }
}
专用异步任务LoadAutocomplete(IList resp)
{
var client=new AmazonDynamoDBClient();
foreach(resp中的var项目)
{
var请求=新的PutItemRequest
{
TableName=EnvironmentHelper.DynamoTableName,
Item=新字典()
{
{“语言”,新属性值{S=item.LANGUAGE},
{“国家”,新属性值{S=item.COUNTRY}
}
};
等待client.PutItemAsync(请求);
系统线程线程睡眠(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);
    }
}
专用异步任务LoadAutocomplete(IList resp)
{
var client=new AmazonDynamoDBClient();
Parallel.ForEach(resp,异步项=>
{
var请求=新的PutItemRequest
{
TableName=EnvironmentHelper.DynamoTableName,
Item=新字典()
{
{“语言”,新属性值{S=item.LANGUAGE},
{“国家”,新属性值{S=item.COUNTRY}
}
};
等待client.PutItemAsync(请求);
}
}
选项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);
}
专用异步任务LoadAutocomplete(IList resp)
{
var client=new AmazonDynamoDBClient();
var tasks=items.Select(x=>DoSomethingAsync(client,x)).ToList();
等待任务。何时(任务);
}
私人剂量测量(AmazondynamodClient客户端,项目)
{
var请求=新的PutItemRequest
{
TableName=EnvironmentHelper.DynamoTableName,
Item=新字典()
{
{“语言”,新属性值{S=item.LANGUAGE},
{“国家”,新属性值{S=item.COUNTRY}
}
};
等待client.PutItemAsync(请求);
}
选项+由@martin建议


这篇文章确实回答了我的问题,但我选择了@jamesfaix发布,因为它极大地改进了我的代码。

这里是我开始时要做的一些基本更改。可能还有其他改进

  • 避免异步代码中的
    Thread.Sleep
    Task.Delay
    是异步等价物
  • 在等待任何任务之前创建多个任务。运行时将尝试同时运行一些任务(如果可以)
  • 专用异步任务LoadAutocomplete2(IList resp)
    {
    var client=new AmazonDynamoDBClient();
    var tasks=resp.Select(异步项=>
    {
    var请求=新的PutItemRequest
    {
    TableName=EnvironmentHelper.DynamoTableName,
    Item=新字典()
    {
    {“语言”,新属性值{S=item.LANGUAGE},
    {“国家”,新属性值{S=item.COUNTRY}
    }
    };
    var result=await client.PutItemAsync(请求);
    等待任务。延迟(100);
    返回结果;
    })
    .ToList();//确保实现IEnumerable!
    等待任务。何时(任务);
    }
    
    以下是我开始时要做的一些基本更改。您还可以从中进行其他改进

  • 避免异步代码中的
    Thread.Sleep
    Task.Delay
    是异步等价物
  • 在等待任何任务之前创建多个任务。运行时将尝试同时运行一些任务(如果可以)
  • 专用异步任务LoadAutocomplete2(IList resp)
    {
    var client=new AmazonDynamoDBClient();
    var tasks=resp.Select(异步项=>
    {
    var请求=新的PutItemRequest
    {
    TableName=EnvironmentHelper.DynamoTableName,
    Item=新字典()
    {
    {“语言”,新属性值{S=item.LANGUAGE},
    {“国家”,新属性值{S=item.COUNTRY}
    }
    };
    var result=await client.PutItemAsync(请求);
    等待任务。延迟(100);
    返回结果;
    })
    .ToList();//确保实现IEnumerable!
    等待任务。何时(任务);
    }
    
    不要在异步代码中使用
    Sleep
    。使用
    等待任务。延迟
    啊,是的。我实际上已经删除了那一行,但忘了在这里。我可能会被它难住,因为我似乎记得需要那一行来确保DB插入正确执行。在选项1和选项2之间,我更关心的是行为的不同比语法更简洁。您可以不费吹灰之力就拒绝“选项1”。
    Parallel.ForEach
    。您在“DB插入正确执行”中提到过,通过在操作之间添加100毫秒的延迟。在异步代码中不要使用
    Sleep
    。使用
    wait Task.delay
    啊,是的。我实际上已经删除了该行,但忘了在这里。无论如何,我可能会被它难倒,因为我似乎记得需要该行来确保DB插入正确执行。在选项1和选项2之间,我将ld更关心的是行为差异而不是语法清洁度。您可以不费吹灰之力就拒绝“选项1”。
    Parallel.ForEach
    。您在文章中提到的“DB插入正确执行”,在操作之间增加了100毫秒的延迟。谢谢@jamesfaix-这将执行时间从1:20缩短到了0:03:)为什么它对我很重要
    private async Task<int> LoadAutocomplete2(IList<Item> resp)
    {
        var client = new AmazonDynamoDBClient();
    
        var tasks = resp.Select(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 }}
                }
            };
    
            var result = await client.PutItemAsync(request);
            await Task.Delay(100);
            return result;
        })
        .ToList(); // Make sure to materialize the IEnumerable!
    
        await Task.WhenAll(tasks);
    }