我目前正在使用Google Drive的.NET API,并且正在尝试从驱动器中下载多个文件。可以在here(以下是我的版本)中找到Google在示例中使用的代码
在.NET Core控制台项目中,我遍历文件列表并尝试一次下载一个文件,例如:
foreach (var file in driveFiles) {
var fileId = file.Id;
var request = driveService.Files.Get(fileId);
var stream = new System.IO.MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged +=
(IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
break;
}
}
};
request.Download(stream);
// .. carry on processing
}
我的问题是我有大约300个文件的列表。上面的代码同时触发了所有300次下载,我看到了每次下载的进度。我想要发生的是每次下载一次发生一次,即。我先关闭第一个下载,然后代码等待下载完成,然后再继续进行下一个下载。
我试图通过设置一个布尔值来做到这一点,该布尔值仅在下载完成或失败后才更新,但这似乎不起作用:
foreach (var file in driveFiles) {
var fileId = file.Id;
var request = driveService.Files.Get(fileId);
var stream = new System.IO.MemoryStream();
bool processingComplete = false;
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged +=
(IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
processingComplete = true;
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
processingComplete = true;
break;
}
}
};
request.Download(stream);
while (!processingComplete) ;
processingComplete = false;
}
但是,这似乎不起作用,并且代码似乎继续具有相同的行为。
我对做什么感到困惑。有人有什么想法吗?
答案 0 :(得分:0)
您的问题是您要为每个文件启动单独的任务。即使我无法弄清楚您的代码的哪一部分实际上在这里做多任务处理。我看不到任何明显的问题,例如await,Threads之类。您需要执行循环的一项任务。基本上,您必须等待请求完成,然后再进行下一个练习。
通常,“按文件”多任务处理是没有好处的。通常,瓶颈是磁盘或网络之类的东西。联网是一种偶然的情况- 可能而且经常有益于同时下载多个文件,即使是从同一端点下载也是如此。使用google API,它们可能由不同的服务器(地理广播IIRC)提供服务,提供者端可能会设置带宽限制,等等。
答案 1 :(得分:0)
因此,根据法比奥的评论,似乎请求确实具有DownloadAsync方法。我已经实现了这一点,这似乎可以解决我的问题:
foreach (var file in driveFiles) {
var fileId = file.Id;
var request = driveService.Files.Get(fileId);
var stream = new System.IO.MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged +=
(IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
break;
}
}
};
IDownloadProgress result = await request.DownloadAsync(stream);
}