【问题标题】:Why can I only do 2 concurrent downloads with the .NET GDrive API v3?为什么我只能使用 .NET GDrive API v3 进行 2 次并发下载?
【发布时间】:2021-02-07 19:20:59
【问题描述】:

我不确定这是客户端限制还是 API 限制,但我似乎无法使用 .NET GDrive API 进行超过 2 个并发下载。这给我的应用程序带来了一个大问题,因为如果用户想要一次下载超过 2 个文件,如果前 2 个下载没有及时完成,那么所有其他“排队”的下载最终都会超时,这也会引发System.Threading.Tasks.TaskWasCanceled 就我而言,因为我使用的是 FilesResource.GetRequest.DownloadAsync

我是否可以更改某种属性以允许超过 2 个并发下载,或者在引发异常之前增加超时?

这是我目前的下载功能:

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;
    }
}

如果我需要提供任何其他详细信息,请告诉我!

【问题讨论】:

  • 您阅读文档了吗?通过同一个应用程序,您可能仅限于几个并发下载。如果是这种情况,我们无法帮助您。但是,就像这个世界上的所有事物一样,您可能会以某种方式向他们付款并增加它。但这是推测性的
  • @TheGeneral API 缺少很多文档,所以没什么可看的。我不确定限制是客户端还是API限制,这就是我在这里问的原因,也许有人知道,也许我需要在某处设置一个属性,指定最大允许连接/下载,我不知道任何线索.我是 API 新手,除了以前遇到过这个问题的人,或者比我更了解 API 的人之外,我真的没有其他地方可以得到帮助。
  • 可能是这样的:docs.microsoft.com/en-us/dotnet/api/…。非 asp.net 应用的默认值为 2,尝试在应用程序开始时将其设置为更大的值
  • @Evk 非常感谢,它有效!我从来没有想过这个大声笑。

标签: c# .net wpf google-drive-api


【解决方案1】:

看起来您可以设置服务的 HttpClient.Timeout 属性,这解决了我的问题。我仍然不能同时下载超过 2 个,但这已经足够了。我的主要问题是我的函数引发了 TaskWasCanceled 异常。如果有人知道如何允许超过 2 个并发下载,请对此答案发表评论!无论哪种方式,这是一个例如设置超时(假设service 是您的新DriveService 实例):

service = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = gDriveUserCredential,
    ApplicationName = ApplicationName
});
service.HttpClient.Timeout = Timeout.InfiniteTimeSpan;

编辑:感谢@Evk 的并发下载修复。在我的应用程序启动时设置ServicePointManager.DefaultConnectionLimit 属性似乎工作得很好,例如:

ServicePointManager.DefaultConnectionLimit = 4;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多