Reputation: 21
I'm not sure if this is a client or an API limitation, but I can't seem to do more than 2 concurrent downloads with the .NET GDrive API. This causes a big problem for my application, because if the user wants to download more than 2 files at once, all the other "queued" downloads will timeout eventually if the first 2 downloads aren't completed in time, which will also raise a System.Threading.Tasks.TaskWasCanceled
in my case, since I'm using FilesResource.GetRequest.DownloadAsync
.
Is there some sort of property that I can change to allow more than 2 concurrent downloads, or to increase the timeout before it raises an exception?
Here's my current download function:
public static async Task DownloadFile(string name, string downloadPath, string extractPath, string appExePath, GridButton clickedGridBtn)
{
name += ".zip";
downloadPath += ".zip";
foreach (Google.Apis.Drive.v3.Data.File gDriveFile in filesList)
{
if (!gDriveFile.Name.Equals(name))
continue;
Utils.CreateDirIfNotExist(ConfigUtils.downloadPath);
clickedGridBtn.Btn.IsEnabled = false;
DownloadProgressPanel dlProgressPanel = new DownloadProgressPanel() { AppIconPath = $"/Resources/Icons/{name.Replace(".zip", string.Empty)}" };
UIElementCollection dlProgressWindowChildren = MainWindow.Instance.DlProgressPanelStack.Children;
bool alreadyExists = false;
foreach (DownloadProgressPanel dlPanel in dlProgressWindowChildren)
{
if (dlPanel.AppIconPath.Equals(dlProgressPanel.AppIconPath))
{
int index = dlProgressWindowChildren.IndexOf(dlPanel);
dlProgressWindowChildren.RemoveAt(index);
dlProgressWindowChildren.Insert(index, dlProgressPanel);
alreadyExists = true;
break;
}
}
if (!alreadyExists)
dlProgressWindowChildren.Add(dlProgressPanel);
MainWindow.Instance.TabButton_Click(MainWindow.Instance.DownloadsTabBtn);
FileStream dlFileStream = new FileStream(downloadPath, FileMode.OpenOrCreate);
FilesResource.GetRequest fileReq = service.Files.Get(gDriveFile.Id);
long? fileSize = gDriveFile.Size;
dlProgressPanel.DownloadSizeText.Text = $"Downloading... 0 MB of {Utils.ConvertToGigabytes(fileSize)}";
dlProgressPanel.DLProgressBar.Value = Utils.ConvertToPercentage(0.0, (double)fileSize);
fileReq.MediaDownloader.ChunkSize = 204800;
fileReq.MediaDownloader.ProgressChanged += (IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
UpdateProgressValues(progress, fileSize, dlProgressPanel);
break;
case DownloadStatus.Completed:
UpdateProgressValues(progress, fileSize, dlProgressPanel);
dlFileStream.Dispose();
dlFileStream.Close();
DownloadCompleted(dlProgressPanel, clickedGridBtn, downloadPath, extractPath, appExePath);
break;
case DownloadStatus.Failed:
Console.WriteLine($"Failed to download \"{name}\"!");
break;
}
};
await fileReq.DownloadAsync(dlFileStream);
break;
}
}
If I need to provide any other details, please tell me!
Upvotes: 1
Views: 69
Reputation: 21
Looks like you can set the service's HttpClient.Timeout
property, which fixed my issue. I still can't do more than 2 concurrent downloads, but this is enough. My main issue was my function raising the TaskWasCanceled exception. If anybody knows how to allow more than 2 concurrent downloads, please comment on this answer! Either way, here's an e.g. of setting the timeout (assuming service
is your new DriveService
instance):
service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = gDriveUserCredential,
ApplicationName = ApplicationName
});
service.HttpClient.Timeout = Timeout.InfiniteTimeSpan;
EDIT: Thanks to @Evk for the concurrent downloads fix. Setting the ServicePointManager.DefaultConnectionLimit
property at the startup of my application seems to work just fine, e.g:
ServicePointManager.DefaultConnectionLimit = 4;
Upvotes: 1