C# 虽然不能与AWS进行太多的合作,但您似乎向API发出了大量的请求。我希望这会受到严重的I/O限制,所以您真的不应该一次只做几个。API允许您点击的频率可能有一个速率限制。同意,听起来您想限制此处所述的并发请求量:在VS代码中运行实际上可能会使其速度减慢(由

C# 虽然不能与AWS进行太多的合作,但您似乎向API发出了大量的请求。我希望这会受到严重的I/O限制,所以您真的不应该一次只做几个。API允许您点击的频率可能有一个速率限制。同意,听起来您想限制此处所述的并发请求量:在VS代码中运行实际上可能会使其速度减慢(由,c#,amazon-web-services,asynchronous,task,C#,Amazon Web Services,Asynchronous,Task,虽然不能与AWS进行太多的合作,但您似乎向API发出了大量的请求。我希望这会受到严重的I/O限制,所以您真的不应该一次只做几个。API允许您点击的频率可能有一个速率限制。同意,听起来您想限制此处所述的并发请求量:在VS代码中运行实际上可能会使其速度减慢(由于网络延迟),以至于没有达到速率限制。从EC2实例调用它可能会更快地进行调用,从而达到速率限制。您是否在本地运行代码而不是在VS代码中运行代码时遇到同样的问题?您是否尝试过从Visual Studio运行代码,但没有附加调试程序?(Ctrl+F


虽然不能与AWS进行太多的合作,但您似乎向API发出了大量的请求。我希望这会受到严重的I/O限制,所以您真的不应该一次只做几个。API允许您点击的频率可能有一个速率限制。同意,听起来您想限制此处所述的并发请求量:在VS代码中运行实际上可能会使其速度减慢(由于网络延迟),以至于没有达到速率限制。从EC2实例调用它可能会更快地进行调用,从而达到速率限制。您是否在本地运行代码而不是在VS代码中运行代码时遇到同样的问题?您是否尝试过从Visual Studio运行代码,但没有附加调试程序?(Ctrl+F5)我确实在开始时尝试了WhAll,当它开始悬挂时,我改为WhenAny,以便能够观察到它悬挂的位置。。。我会调查你的解决方案@kintax:
OrderedApitask
应为
列表
。此修改无任何更改:(您是否尝试过限制您的连接?很好,您已经开始工作了。如果性能很重要,您可能希望尝试使用例如ParallelForEachAsync from来实现N个活动任务的滑动窗口,而不是等待每批中的N个任务全部完成。
namespace MyNamespace
{
    public class MyClass
    {
        private static DataTable dt;
        private static IAmazonS3 clientS3;

        static async Task Main(string[] args)
        {
            dt = <Call DB, get S3 URIs>;
            clientS3 = new AmazonS3Client();

            IEnumerable<Task<int>> callApiTasksQuery = from row in dt.AsEnumerable() select GetS3DataAsync(row);
            List<Task<int>> apiTasks = callApiTasksQuery.ToList();

            int total = 0;
            while (apiTasks.Any())
            {
                // if (apiTasks.Count % 100 == 0) await Console.Out.WriteLineAsync($"{apiTasks.Count} remaining.");
                Task<int> finishedTask = await Task.WhenAny(apiTasks);
                apiTasks.Remove(finishedTask);
                total += await finishedTask;
            }
        }
        
        static async Task<int> GetS3DataAsync(DataRow row)
        {
            var response = await clientS3.ListObjectsV2Async(new ListObjectsV2Request { BucketName = row[0], Prefix = row[1] });
            // Console.WriteLine(response.S3Objects.Count().ToString());  
            return 1;
        }
    }
}
int total = 0;
while (apiTasks.Any())
{
  // if (apiTasks.Count % 100 == 0) await Console.Out.WriteLineAsync($"{apiTasks.Count} remaining.");
  Task<int> finishedTask = await Task.WhenAny(apiTasks);
  apiTasks.Remove(finishedTask);
  total += await finishedTask;
}
var totals = await Task.WhenAll(apiTasks);
var total = totals.Sum();
int total = 0;
var orderedApiTasks = apiTasks.OrderByCompletion();
for (int i = 0; i != orderedApiTasks.Count; ++i)
{
  total += await orderedApiTasks[i];
  if (i % 100 == 0) await Console.Out.WriteLineAsync($"{orderedApiTasks.Count - i} remaining.");
}
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Data;
using Amazon.S3;
using System.Linq;
using Amazon.S3.Model;

namespace MyNamespace
{
    public class S3PrefixGrabber
    {
        private static IAmazonS3 clientS3;

        static async Task Main(string[] args)
        {
            var query = "SELECT bucket,prefix from myTable";
            DataTable dt = GetStuffFromDB(query);
            List<S3Prefix> unpopulatedList = (from DataRow dr in dt.Rows select new S3Prefix() { B = dr[0].ToString(), P = dr[1].ToString() }).ToList();

            var batchSize = 1000;
            int numberOfBatches = (int)Math.Ceiling((double)unpopulatedList.Count() / batchSize);
            List<S3Prefix> populatedList = new List<S3Prefix>();

            for (int i = 0; i < numberOfBatches; i++)
            {
                var currentItems = unpopulatedList.Skip(i * batchSize).Take(batchSize);
                var tasks = currentItems.Select(id => GetS3DataAsync(id));
                populatedList.AddRange(await Task.WhenAll(tasks));
            }
        }

        static async Task<S3Prefix> GetS3DataAsync(S3Prefix s3Item)
        {
            clientS3 = new AmazonS3Client();
            var response = await clientS3.ListObjectsV2Async(new ListObjectsV2Request { BucketName = s3Item.B, Prefix = s3Item.P });
            s3Item.O = response.S3Objects.Count;

            return s3Item;
        }
    }

    public class S3Prefix
    {
        public string B { get; set; }
        public string P { get; set; }
        public int O { get; set; }
    }
}