【问题标题】:HttpClient getAsync hanging on larger filesHttpClient getAsync 挂在较大的文件上
【发布时间】:2017-03-29 07:58:07
【问题描述】:

很抱歉,如果之前已经回答过这个问题,但没有一个答案对我有帮助。我的 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);。这也会挂起。

【问题讨论】:

  • 您是否更新了 config 中的 maxRequestLength 属性?您是否也考虑过将 GetAsync 更改为 ReadAsStreamAsync 并将 Stream 写入文件?我认为该文件不会下载到内存中,而是直接保存到文件中。

标签: c# file download uwp httpclient


【解决方案1】:

也许对于较大的文件,最好使用

Windows.Networking.BackgroundTransfer

命名空间,比如BackgroundDownloader?

【讨论】:

  • 据我所知,您在后台下载器中找不到文件名。这是强制性的。还是我错过了什么?
【解决方案2】:

请将您的代码更改为-

var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false));

另请参阅-HttpClient.GetAsync(...) never returns when using await/async

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

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

【讨论】:

  • 方法 .ConfigureAwait() 不适用于 Windows.Web.Http.HttpClient.GetAsync 方法。正如我所说,我正在使用 Windows.Web.Http.HttpClient。我会尝试你的第二个建议!
  • 对于您的第二个建议,我收到了这个异常:(来自 HRESULT 的异常:0x8001010E (RPC_E_WRONG_THREAD))'
  • 哦,我明白了。您可以使用“System.Net.Http.HttpClient”还是有特殊原因这样做。如果您仍想使用当前的实现,您可以使用取消令牌和超时。最好设置一个超时以避免无限期等待。参考-stackoverflow.com/questions/19535004/…
  • 如果您要下载大文件,那么 httpclient 将不适合。使用后台下载器。 github.com/Kumara-Krishnan/Windows-universal-samples/tree/…
  • @Souvik Ghosh 在 getasync 之前使用 await 将使应用程序等待文件下载。使用 task.run 将无济于事,因为即使您使用 configureAwait(false),httpclient.getasync 也会切换到 UI 线程。取消令牌在这里没有任何作用,因为 10 mb 文件比下载 2 mb 文件需要更长的时间。
猜你喜欢
  • 2013-11-03
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
相关资源
最近更新 更多