首页 > 解决方案 > 使用相同的 AmazonS3Client 实例进行并行请求?

问题描述

我有下面的代码,可以使用 AmazonS3Client 从 S3 并行下载多个文件。这一直运作良好。

public async Task Download(IList<string> urls, int maxConcurrentDownloads)
{
        var output = new List<Stream>();
        var tasks = new List<Task>();
        for (int i = 0; i < urls.Count; i++)
        {
            
            AmazonS3Uri s3Uri = null;
            if (AmazonS3Uri.TryParseAmazonS3Uri(urls[i], out s3Uri))
            {
                var ms = new MemoryStream();
                output.Add(ms);
                tasks.Add(GetObject(s3Uri,ms));
            }

            if (tasks.Count == maxConcurrentDownloads || i == urls.Count - 1)
            {
                await Task.WhenAll(tasks);
                tasks.Clear();
            }
        }                        
}

private async Task GetObject(AmazonS3Uri s3Uri, Stream output)
{
    using (var s3Client = new AmazonS3Client(s3Uri.Region))
    {
       // removed for brevity purpose
       await s3Client.GetObjectAsync(...);
    }
}

所有 URL 都在同一个区域中。AmazonS3Client上面的代码为每个 URL创建了新的实例。所以我重构了代码以使用AmazonS3Client.

public async Task Download(IList<string> urls, int maxConcurrentDownloads)
{
        var output = new List<Stream>();
        var tasks = new List<Task>();
        using(AmazonS3Client s3Client = new AmazonS3Client())
        {
            for (int i = 0; i < urls.Count; i++)
            {
                AmazonS3Uri s3Uri = null;
                if (AmazonS3Uri.TryParseAmazonS3Uri(urls[i], out s3Uri))
                {
                    var ms = new MemoryStream();
                    output.Add(ms);
                    tasks.Add(GetObject(s3Client,s3Uri,ms));
                }

                if (tasks.Count == maxConcurrentDownloads || i == urls.Count - 1)
                {
                    await Task.WhenAll(tasks);
                    tasks.Clear();
                }
            }
       }            
}

private async Task GetObject(AmazonS3Client s3Client, AmazonS3Uri s3Uri, Stream output)
{
    // download file using provided s3Client
    await s3Client.GetObjectAsync(...);
}

问题

  1. 给定 maxConcurrentDownloads = 20,是否建议使用 S3Client 的单个实例并行下载或上传?

  2. 默认值AmazonS3Config.ConnectionLimit是 50,是不是意味着 S3Client 的单个实例可以同时下载或上传 50 个文件?

  3. 或者更好的是,我应该使用 Amazons3Client 的 Singleton 实例吗?

有什么建议吗?

标签: c#amazon-s3aws-sdk.net-4.7.2aws-sdk-net

解决方案


推荐阅读