代码之家  ›  专栏  ›  技术社区  ›  MrCSharp

流动第一次调用时的ReadAsync()非常慢

  •  0
  • MrCSharp  · 技术社区  · 9 年前

    我正在编写一个类来处理文件下载,我正在使用以下代码[简化]:

    var webRequest = (HttpWebRequest)WebRequest.Create(downloadOperation.Link);
    webRequest.Proxy = null;
    using (var webResponse = await webRequest.GetResponseAsync())
    {
        using (var downloadStream = webResponse.GetResponseStream())
        {
            using (var outputFileWriteStream = await outputFile.OpenStreamForWriteAsync())
            {
                var buffer = new byte[4096];
                var downloadedBytes = 0;
                var totalBytes = webResponse.ContentLength;
                while (downloadedBytes < totalBytes)
                {
                    //*************************THIS LINE TAKES ABOUT 32 SECONDS TO EXECUTE ON FIRST INVOKE, ALL NEXT INVOKES TAKE ABOUT 120MS***************************
                    var currentRead = await downloadStream.ReadAsync(buffer, 0, buffer.Length);
                    //*******************************************************************************************************************************************************************
    
                    await outputFileWriteStream.WriteAsync(buffer, 0, currentRead); 
                }
            }
        }
    }
    

    你能解释一下为什么第一次调用要花那么长时间,而下一次调用却没有?我担心它会在第一次读取时下载整个文件。

    请注意,文件通常在3~15MB之间。

    2 回复  |  直到 9 年前
        1
  •  1
  •   Kevin Gosse    9 年前

    我担心它会在第一次读取时下载整个文件。

    这正是正在发生的事情。您可以通过设置 webRequest.AllowReadStreamBuffering false .

        2
  •  0
  •   MrCSharp    9 年前

    所以我找到了解决这个问题的方法,但它不使用WebRequest类。

    我现在正在使用(Windows.Web.Http)中的HttpClient。

    以下是固定代码:

        var client = new Windows.Web.Http.HttpClient(); // prepare the http client 
    
    //get the response from the server
    using (var webResponse = await client.GetAsync(downloadOperation.Link, HttpCompletionOption.ResponseHeadersRead)) //***********Node the HttpCompletionOption.ResponseHeaderRead, this means that the operation completes as soon as the client receives the http headers instead of waiting for the entire response content to be read
    {
        using (var downloadStream = (await webResponse.Content.ReadAsInputStreamAsync()).AsStreamForRead() )
        {
            using (var outputFileWriteStream = await outputFile.OpenStreamForWriteAsync())
            {
                var buffer = new byte[4096];
                var downloadedBytes = 0;
                var totalBytes = webResponse.ContentLength;
                while (downloadedBytes < totalBytes)
                    {
                        //*************************THIS LINE NO LONGER TAKES A LONG TIME TO PERFORM FIRST READ***************************
                        var currentRead = await downloadStream.ReadAsync(buffer, 0, buffer.Length);
                        //*******************************************************************************************************************************************************************
    
                        await outputFileWriteStream.WriteAsync(buffer, 0, currentRead); 
                    }
            }
    
        }
    
    }
    

    希望这能帮助到其他人;)

    谢谢大家