Stream.ReadAsync() 第一次调用时非常慢

Stream.ReadAsync() on first invoke very slow

我正在编写 class 来处理文件下载,我正在使用此代码 [简化]:

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 之间。

I am worried that it is downloading the entire file on the first read.

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

来更改它

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

我现在正在使用 (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); 
                }
        }

    }

}

希望这会对外面的人有所帮助 ;)

谢谢大家