【发布时间】:2020-02-24 01:23:45
【问题描述】:
我正在编写一个控制台应用程序来在旧系统和新版本之间进行一些数据迁移。每条记录都有存储在一个 Web 服务器上的关联图像,我正在将每个图像下载/更改/上传到 Azure(并且还在数据库中记录有关每个图像的一些数据)。
这是一个粗略的大纲,在代码中:
public void MigrateData()
{
var records = GetRecords();
foreach (var record in records)
{
// ...
MigrateImages(record.Id, record.ImageCount);
}
}
public void MigrateImages(int recordId, int imageCount)
{
for (int i = 1; i <= imageCount; i++)
{
var legacyImageData = DownloadImage("the image url");
if (legacyImageData != null && legacyImageData.Length > 0)
{
// discard because we don't need the image id here, but it's used in other workflows
var _ = InsertImage(recordId, legacyImageData);
}
}
}
// This method can be used elsewhere, so the return of int is necessary and cannot be changed
public int InsertImage(int recordId, byte[] imageData)
{
var urls = UploadImage(imageData).Result;
return // method call to save image and return image ID
}
public async Task<(Uri LargeUri, Uri ThumbnailUri)> UploadImage(byte[] imageData)
{
byte[] largeData = ResizeImageToLarge(imageData);
byte[] thumbnailData = ResizeImageToThumbnail(imageData);
var largeUpload = largeBlob.UploadFromByteArrayAsync(largeImage, 0, largeImage.Length);
var thumbUpload = thumbsBlob.UploadFromByteArrayAsync(thumbImage, 0, thumbImage.Length);
await Task.WhenAll(largeUpload, thumbUpload);
var largeUrl = "";// logic to build url
var thumbUrl = "";// logic to build url
return (largeUrl, thumbUrl);
}
我正在为 UploadImage() 使用 async/await 以允许并行上传大图和缩略图,从而节省时间。
我的问题是(如果可能/有意义)我如何利用 async/await for MigrateImages() 进行并行图像上传,以减少完成任务所需的总时间?我已经在 UploadImage() 中使用 async/await 的事实是否阻碍了我的目标?
由于我的问题,这可能很明显,但是等待/异步仍然是我无法完全理解如何正确使用和/或实现它的东西。
【问题讨论】:
-
InsertImage应该是异步的并等待UploadImage而不是调用Result。当InsertImage是异步时,您可以在MigrateImages中使用与UploadImage中相同的模式来运行多个“插入” => 启动多个异步操作并使用Task.WhenAll等待它们 -
“上传”这个词意味着您受 I/O 限制,而不是 CPU 限制。您需要确定并行化是否会使您受益。如果瓶颈是网络速度,那么将更多数据投入瓶颈不会提高任何速度。
-
@DanielMann 我正在尝试并行化上传图像的过程。 “同时”上传 10 张图片应该比串行上传更快,是吗?
-
没有。如果您可以每秒上传 1 MB,并且您已经在上传每秒 1 MB,那么一次上传两个文件意味着您以每秒 1 MB 的速度上传,每个文件每秒上传 500 KB。或者其他一些加起来高达 1 MB/s 的比率。
-
@DanielMann 明白,感谢您的澄清。对于这个例子,我们可以假设上传带宽不是限制。
标签: c# async-await