Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用AWS S3 SDK for .NET从Amazon下载并行批处理文件

使用AWS S3 SDK for .NET从Amazon下载并行批处理文件
EN

Stack Overflow用户
提问于 2012-05-07 10:01:00
回答 2查看 7.3K关注 0票数 13

问题:--我想使用他们的.NET SDK,从AWS S3中并行下载100个文件。下载的内容应该存储在100个内存流中(文件足够小,我可以从中提取)。我对任务、IAsyncResult、并行.*以及.NET 4.0中的其他不同方法感到困惑。

--如果我想自己解决这个问题--,从我的头顶上想出这样的伪代码:(编辑以向某些变量添加类型)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;

AmazonS3 _s3 = ...;
IEnumerable<GetObjectRequest> requestObjects = ...;


// Prepare to launch requests
var asyncRequests = from rq in requestObjects 
    select _s3.BeginGetObject(rq,null,null);

// Launch requests
var asyncRequestsLaunched = asyncRequests.ToList();

// Prepare to finish requests
var responses = from rq in asyncRequestsLaunched 
    select _s3.EndGetRequest(rq);

// Finish requests
var actualResponses = responses.ToList();

// Fetch data
var data = actualResponses.Select(rp => {
    var ms = new MemoryStream(); 
    rp.ResponseStream.CopyTo(ms); 
    return ms;
});

此代码并行启动100个请求,这是很好的。然而,有两个问题:

  1. 最后一条语句将按顺序下载文件,而不是并行下载。流中似乎没有BeginCopyTo()/EndCopyTo()方法.
  2. 在所有请求都得到答复之前,上述声明不会放弃。换句话说,在所有文件都启动之前,所有文件都不会开始下载。

所以我开始觉得我走错路了.

帮助?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-07 11:19:03

如果将操作分解为一个方法,异步处理一个请求,然后调用它100次,可能会更容易。

首先,让我们确定您想要的最终结果。因为您将要使用的是一个MemoryStream,这意味着您希望从您的方法返回一个Task。签名将如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static Task<MemoryStream> GetMemoryStreamAsync(AmazonS3 s3, 
    GetObjectRequest request)

因为AmazonS3对象实现了异步设计模式,所以可以使用班级上的方法从实现异步设计模式的类生成Task<T>,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static Task<MemoryStream> GetMemoryStreamAsync(AmazonS3 s3, 
    GetObjectRequest request)
{
    Task<GetObjectResponse> response = 
        Task.Factory.FromAsync<GetObjectRequest,GetObjectResponse>(
            s3.BeginGetObject, s3.EndGetObject, request, null);

    // But what goes here?

因此,您已经在一个好地方了,您有一个Task<T>,您可以在调用完成时等待或调用一个回调。但是,您需要以某种方式将从调用Task<GetObjectResponse>返回的Task<GetObjectResponse>转换为MemoryStream

为此,您希望在方法类上使用Task<T>。把它看作是方法班级上的异步版本,它只是对另一个Task<T>的投影,只不过每次调用ContinueWith时,您都可能会创建一个运行该部分代码的新任务。

这样,您的方法如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static Task<MemoryStream> GetMemoryStreamAsync(AmazonS3 s3, 
    GetObjectRequest request)
{
    // Start the task of downloading.
    Task<GetObjectResponse> response = 
        Task.Factory.FromAsync<GetObjectRequest,GetObjectResponse>(
            s3.BeginGetObject, s3.EndGetObject, request, null
        );

    // Translate.
    Task<MemoryStream> translation = response.ContinueWith(t => {
        using (Task<GetObjectResponse> resp = t ){
            var ms = new MemoryStream(); 
            t.Result.ResponseStream.CopyTo(ms); 
            return ms;
        } 
    });

    // Return the full task chain.
    return translation;
}

请注意,在上面,您可以调用传递ContinueWithTaskContinuationOptions.ExecuteSynchronously,因为您所做的工作似乎很少(我无法判断,响应可能很大)。在您所做的工作非常少的情况下,为了完成工作而启动一个新任务将是有害的,您应该通过TaskContinuationOptions.ExecuteSynchronously,这样就不会浪费时间为最小的操作创建新的任务。

既然有了可以将一个请求转换为Task<MemoryStream>的方法,那么创建一个包装器来处理任意数量的请求就很简单了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static Task<MemoryStream>[] GetMemoryStreamsAsync(AmazonS3 s3,
    IEnumerable<GetObjectRequest> requests)
{
    // Just call Select on the requests, passing our translation into
    // a Task<MemoryStream>.
    // Also, materialize here, so that the tasks are "hot" when
    // returned.
    return requests.Select(r => GetMemoryStreamAsync(s3, r)).
        ToArray();
}

在上面,您只需获取GetObjectRequest实例的序列,它将返回一个Task<MemoryStream>数组。它返回物化序列这一事实很重要。如果在返回之前没有将其具体化,那么在迭代序列之前不会创建任务。

当然,如果您想要这种行为,那么无论如何,只需删除对.ToArray()的调用,让方法返回IEnumerable<Task<MemoryStream>>,然后在迭代任务时发出请求。

在那里,您可以一次一个地处理它们(在循环中使用方法 ),或者等待它们全部完成(通过调用方法)。后者的一个例子是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static IList<MemoryStream> GetMemoryStreams(AmazonS3 s3, 
    IEnumerable<GetObjectRequest> requests)
{
    Task<MemoryStream>[] tasks = GetMemoryStreamsAsync(s3, requests);
    Task.WaitAll(tasks);
    return tasks.Select(t => t.Result).ToList();
}

另外,应该指出,这非常适合于反应性扩展框架,因为这非常适合于IObservable实现。

票数 22
EN

Stack Overflow用户

发布于 2022-03-15 11:08:20

您可以从Nexus.Tasks包中使用Nexus.Core。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var response = await fileNames
.WhenAll(item => GetObject(item, cancellationToken), 10, cancellationToken)
.ConfigureAwait(false);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10486822

复制
相关文章
代码修改后运行结果同修改之前结果一样
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/38039377
DannyHoo
2018/09/13
7840
代码修改后运行结果同修改之前结果一样
老师我纳闷:数据分析的结果该如何落地?
有同学问:“我有个一个很好的分析发现,问题是如何让它落地呢?”还有同学抱怨,感觉发出去的数据分析报告都不见结果。要如何推动数据分析落地?一图以蔽之,推动方式和推动难度,完全取决于“我”是谁
接地气的陈老师
2019/12/09
6100
json_decode的结果是null
突然发现一个接口出了问题,经过排查之后发现是json_decode($str,true)的问题,返回竟然是null。这个问题大家可能都碰到过,出现问题的原因就那么几种,再次记录一下吧
全栈程序员站长
2022/09/09
1.1K0
Python解析psiBlast输出的JSON文件结果
什么是JSON文件 JSON文件是一种轻量级的数据存储和交换格式,其实质是字典和列表的组合。这在定义生信分析流程的参数文件中具有很好的应用。 { "公众号": { "名字": "生信宝典", "宗旨": "为生信服务", "正确地打开方式": [ "阅读", "置顶", "转发" ] } } 在Python中解析JSON是通过如下代码完成的
生信宝典
2018/02/05
2.1K0
利用python修改json文件的val
    做工程时遇到需要监听json文件,根据json文件中的key-value值作出相应处理的情形。为此写了修改json文件的python脚本供工程后续调用。
py3study
2020/01/03
3.1K0
Stimulsoft Web版中如何动态修改Json数据源的Url
在Stimulsoft Report(目前我使用的是2022.1.2版本)中,可以支持从JSON文件或者在线URL作为数据源。
崔文远TroyCui
2022/01/14
1.9K0
Stimulsoft Web版中如何动态修改Json数据源的Url
PHP如何将数据库查询结果输出为json格式
近期做接口的时候需要做到一个操作,将数据库查询结果输出为json格式方便程序调用。 于是在网上看到了两种解法,就此分享出来,供大家学习以及自己日后进行参考。 可将其封装成专门将数据转换成json格式的接口
吃猫的鱼Code
2023/02/02
3.3K0
面试的时候我只会聊项目,结果就把我挂了!
在上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间。我的标准其实不复杂:第一能干活,第二Java基础要好,第三最好熟悉些分布式框架。我相信其它公司招初级开发时,应该也照着这个标准来面的。
田维常
2019/07/16
5820
面试的时候我只会聊项目,结果就把我挂了!
妹子让我看她写的pytest,结果...
陆陆续续断更好久好久了,这么久发生了很多事情,也思考了很多事情。突然发现拖延症已经严重影响到了我。
Python攻城狮
2020/12/21
9160
我和JSON Schema的那些事
哈喽,我是🌲 树酱。今天聊一聊关于我跟Json schema的一些交集,顺便给大家重新梳理下今日这个主角的概念及当下主要的一些应用场景 1.什么是JSON Schema 相信前端童鞋,对JSON应该都很熟悉。JSON (JavaScript Object Notation) 缩写,JSON 是一种数据格式,具有简洁、可读性高、支持广泛的特点JSON。通过JSON 我们可以灵活地来表示任意复杂的数据结构。 比如我们要描述一个人的信息,我们可以用JSON来描述 那JSON Schema又是什么鬼? 🤔 J
树酱
2022/03/09
1.5K0
我和JSON Schema的那些事
plotsr可视化syri变异检测的结果如何修改图例的排布
整个流程是minimap2比对,然后是syri做变异检测,最后使用plotsr这个命令可视化展示结果,用到的命令是
用户7010445
2023/08/23
5400
plotsr可视化syri变异检测的结果如何修改图例的排布
【PY】根据 Excel 中的指示修改 JSON 数据
继上一次友友问了如何处理 Excel 中的数据之后,这次他又遇到了新问题,让我们一起来看看;
sidiot
2023/08/31
2690
【PY】根据 Excel 中的指示修改 JSON 数据
jQuery 操作 JSON 对象 修改 ztree 结构
ztree 引用了系统中 部门试图的数据集结果,存储为一个 json 对象。其中,通过每个数据的 ParentId 来对应关联树状结构。
李郑
2019/12/04
1K0
前端 Fiddler 抓包修改请求响应结果
实际前端开发中,对接线上发布的后端接口,由于业务比较复杂,也设计到以前的库表,开发过程经常会出现部分页面数据不完整,无法对接整个流程,日常前端开发也有其他方式实现功能测试验证:
草帽lufei
2022/07/29
5600
前端 Fiddler 抓包修改请求响应结果
如何从结果集中获得随机结果
全表扫描(Full table Scan) 全表扫描返回表中所有的记录。 执行全表扫描,Oracle读表中的所有记录,考查每一行是否满足WHERE条件。Oracle顺序的读分配给该表的每一个数据块,这样全表扫描能够受益于多块读. 每个数据块Oracle只读一次.
数据和云01
2018/09/10
1.6K0
sqlalchemy和flask-sqlalchemy查询结果转json
Flask-RESTful 有一个专门做这个的东西,叫 marshal_with, 具体介绍在这里:http://flask-restful.readthedocs.org/en/latest/fields.html 我一般都是用它来格式化返回值
stys35
2019/03/12
5.8K0
Docker修改daemon.json后无法启动的问题
最近在整理Docker和Kubernetes中的日志与相关配置,在尝试通过/etc/docker/daemon.json配置Docker的log-driver参数,遇到了Docker无法启动的错误。
大江小浪
2018/09/19
7.1K0
实用 | 盘点抓包修改响应结果的 2 种方式!
在工作中,我们经常需要针对某个接口修改其响应值,以此改变 App 或浏览器实际的渲染结果
AirPython
2022/12/29
1.4K0
实用 | 盘点抓包修改响应结果的 2 种方式!
如何修改 Discourse 的域名
如果你参考了 GitHub 上的安装指南 页面中的内容安装了一个 Discourse 实例后希望对自己安装的实例修改域名的使用手册。 如果你使用的是 Discourse 官方主机服务 的话,请参考 针对 Discourse 的云服务配置你的域名 页面中的详细内容。
HoneyMoose
2021/09/08
3.8K0
如何修改 Discourse 的域名
点击加载更多

相似问题

从google地图中删除所有控件

42

如何从Mapbox地图中删除缩放控件?

28

从开放层地图中删除默认控件Bing

13

C#从列表视图中删除项目,从列表视图外部控件删除

10

Windows phone 8视口控件

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文