HttpClient异步获取大文件时卡住了

4

很抱歉如果这个问题以前已经有答案了,但是没有一个答案能够帮助我。我有一个WebView的事件:

private async void MainWebView_UnviewableContentIdentified(WebView sender, WebViewUnviewableContentIdentifiedEventArgs args)
{
    await downloadFromUri(args.Uri).ConfigureAwait(false);
}

我的downloadFromUri方法会尝试下载一个文件并将其存储在下载文件夹中,最后它将打开该文件:

    static async Task downloadFromUri(Uri uri)
    {
        var url = uri;

        HttpClient client = new HttpClient();

        client.DefaultRequestHeaders.TryAppendWithoutValidation(
          "Authorization Bearer",
              " MYTOKEN"
              );

        Debug.WriteLine("Attempting GET request");

        var response = await client.GetAsync(url);

        Debug.WriteLine("Got response.. checking " + response.StatusCode);


        if (response.IsSuccessStatusCode)
        {
            Debug.WriteLine("Okay, we've got a response");
            var responseFileName = response.Content.Headers.ContentDisposition.FileName;

            Debug.WriteLine("Filename: " + responseFileName);

            var ManualFile = await DownloadsFolder.CreateFileAsync(responseFileName, CreationCollisionOption.GenerateUniqueName);

            Debug.WriteLine("Creating buffer: ");
            var buffer = await client.GetBufferAsync(url);

            Debug.WriteLine("Writing buffer.");
            await Windows.Storage.FileIO.WriteBufferAsync(ManualFile, buffer);

            Debug.WriteLine("Done, opening");

            var openOptions = new Windows.System.LauncherOptions();
            openOptions.DisplayApplicationPicker = true;

            var openFile = await Windows.System.Launcher.LaunchFileAsync(ManualFile, openOptions);
        }
        else
        {
            Debug.WriteLine(response.StatusCode.ToString());
        }     
    }

事情是这样的,这段代码在小PDF或ZIP文件上似乎工作正常。但是当面对大于10MB的PDF文件时,应用程序在以下行处卡住了:
var response = await client.GetAsync(url);
我该怎么做才能让它正常工作呢?非常感谢!
注:我正在使用Windows.Web.Http.HttpClient而不是System.Net.Http.HttpClient。
编辑:我尝试跳过client.GetAsync(url)并直接运行var buffer = await client.GetBufferAsync(url);。这也导致卡住。

你更新了配置文件中的maxRequestLength属性吗? 你是否考虑将GetAsync更改为ReadAsStreamAsync,并将流写入文件?文件不会在内存中下载,而是直接保存到文件中。 - Miłosz Wieczorek
2个回答

3
也许对于较大的文件,最好使用
Windows.Networking.BackgroundTransfer
命名空间,例如 BackgroundDownloader

据我所知,您无法使用后台下载程序找到文件名。这是必须的。或者我有什么遗漏吗? - Koeno

2
请将您的代码更改为 -
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false));

同时参考这个链接- 使用await / async时,HttpClient.GetAsync(...)永远不会返回

或者,您也可以使用TPL将长时间运行的函数作为任务在操作系统线程池中管理。

var result = Task.Run(() => downloadFromUri(uri)).Result;

方法.ConfigureAwait()在Windows.Web.Http.HttpClient.GetAsync方法中不可用。就像我说的,我正在使用Windows.Web.Http.HttpClient。我会尝试您的第二个建议! - Koeno
1
哦,我明白了。你可以使用'System.Net.Http.HttpClient'吗?还是有特定的原因要这样做?如果你仍然想继续使用当前的实现,你可以使用取消标记和超时。最好设置一个超时时间以避免无限等待。参考- https://dev59.com/4njZa4cB1Zd3GeqPcEnY - Souvik Ghosh
我使用了你的建议: var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).AsTask(source.Token); 这是我目前正在使用的代码。 - Koeno
2
如果你要下载大文件,那么httpclient就不适合了。请使用后台下载器。https://github.com/Kumara-Krishnan/Windows-universal-samples/tree/master/Samples/BackgroundTransfer - Razor
3
在调用getasync之前使用await会使应用程序等待文件下载完成。即使使用configureAwait(false),使用task.run也无法解决httpclient.getasync在下载文件时会切换到UI线程的问题。在这里,取消标记并没有任何作用,因为下载10MB文件所需的时间比下载2MB文件要长。 - Razor
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接