与 WebClient 并行上传文件
Upload Files in Parallel with WebClient
我需要在项目中使用WebClient将一个文件拆分成多个部分并并行上传。到目前为止,我可以一次上传一个部分,但不确定如何并行上传它们。
我有一个 UploadPart 方法,如下所示:
private async Task<PartETag> UploadPart(string filePath, string preSignedUrl, int partNumber)
{
WebClient wc = new();
wc.UploadProgressChanged += WebClientUploadProgressChanged;
wc.UploadFileCompleted += WebClientUploadCompleted;
_ = await wc.UploadFileTaskAsync(new Uri(preSignedUrl), "PUT", filePath);
// Obtain the WebHeaderCollection instance containing the header name/value pair from the response.
WebHeaderCollection myWebHeaderCollection = wc.ResponseHeaders;
string formattedETag = myWebHeaderCollection.GetValues("ETag").FirstOrDefault().Replace(@"""", "");
PartETag partETag = new(partNumber, formattedETag);
return partETag;
}
它在 foreach 循环中调用:
foreach (var part in parts)
{
var partETag = await UploadPart(part.FilePath, part.PresignedUrl, part.Number);
partETags.Add(partETag);
}
我如何修改它以便并行上传部分(一次最多 10 个部分)同时仍然在响应中返回 PartETag 值 header?
这是 TPL Dataflow 的完美场景:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
var parts = new List<Part>();
var partEtags = new List<PartETag>();
var transformBlock = new TransformBlock<Part, PartETag>
(
async part => await UploadPart(part.FilePath, part.PreSignedUrl, part.PartNumber),
new ExecutionDataflowBlockOptions {MaxDegreeOfParallelism = 10}
);
var actionBlock = new ActionBlock<PartETag>(partETag => partEtags.Add(partETag));
transformBlock.LinkTo(actionBlock, new DataflowLinkOptions {PropagateCompletion = true});
foreach (Part part in parts)
{
transformBlock.Post(part);
}
transformBlock.Complete();
await actionBlock.Completion;
我对您的 类 做了一些假设,因为您没有显示所有代码。顶部的 parts
列表显然需要包含实例。
这段代码创建了一个异步执行工作的数据流,并将并行执行的上限限制为 10。这些块与传播的完成链接在一起,因此我们等待操作块的完成以确保一切都完成。
完成后,您的 partEtags
列表将包含您的所有结果。
我需要在项目中使用WebClient将一个文件拆分成多个部分并并行上传。到目前为止,我可以一次上传一个部分,但不确定如何并行上传它们。
我有一个 UploadPart 方法,如下所示:
private async Task<PartETag> UploadPart(string filePath, string preSignedUrl, int partNumber)
{
WebClient wc = new();
wc.UploadProgressChanged += WebClientUploadProgressChanged;
wc.UploadFileCompleted += WebClientUploadCompleted;
_ = await wc.UploadFileTaskAsync(new Uri(preSignedUrl), "PUT", filePath);
// Obtain the WebHeaderCollection instance containing the header name/value pair from the response.
WebHeaderCollection myWebHeaderCollection = wc.ResponseHeaders;
string formattedETag = myWebHeaderCollection.GetValues("ETag").FirstOrDefault().Replace(@"""", "");
PartETag partETag = new(partNumber, formattedETag);
return partETag;
}
它在 foreach 循环中调用:
foreach (var part in parts)
{
var partETag = await UploadPart(part.FilePath, part.PresignedUrl, part.Number);
partETags.Add(partETag);
}
我如何修改它以便并行上传部分(一次最多 10 个部分)同时仍然在响应中返回 PartETag 值 header?
这是 TPL Dataflow 的完美场景:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
var parts = new List<Part>();
var partEtags = new List<PartETag>();
var transformBlock = new TransformBlock<Part, PartETag>
(
async part => await UploadPart(part.FilePath, part.PreSignedUrl, part.PartNumber),
new ExecutionDataflowBlockOptions {MaxDegreeOfParallelism = 10}
);
var actionBlock = new ActionBlock<PartETag>(partETag => partEtags.Add(partETag));
transformBlock.LinkTo(actionBlock, new DataflowLinkOptions {PropagateCompletion = true});
foreach (Part part in parts)
{
transformBlock.Post(part);
}
transformBlock.Complete();
await actionBlock.Completion;
我对您的 类 做了一些假设,因为您没有显示所有代码。顶部的 parts
列表显然需要包含实例。
这段代码创建了一个异步执行工作的数据流,并将并行执行的上限限制为 10。这些块与传播的完成链接在一起,因此我们等待操作块的完成以确保一切都完成。
完成后,您的 partEtags
列表将包含您的所有结果。