简体   繁体   English

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

[英]Stream.ReadAsync() on first invoke very slow

I am writing a class to handle file downloads and i am using this code [simplified]: 我正在编写一个类来处理文件下载,并且正在使用此代码[简体]:

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

Can you please explain to me why is it taking that long on first invoke and not on the next ones? 能否请您解释一下为什么第一次调用花了这么长时间而不是下一次调用花了那么长时间? I am worried that it is downloading the entire file on the first read. 我担心它会在第一次读取时下载整个文件。

Note that the files are usually between 3~15MB. 请注意,文件通常在3〜15MB之间。

I am worried that it is downloading the entire file on the first read. 我担心它会在第一次读取时下载整个文件。

That's precisely what's happening. 这就是正在发生的事情。 You can change that by setting webRequest.AllowReadStreamBuffering to false . 您可以通过将webRequest.AllowReadStreamBuffering设置为false来更改它。

So i found a way to fix this problem, but it doesn't use WebRequest class. 所以我找到了一种解决此问题的方法,但它没有使用WebRequest类。

I am now using the HttpClient found in (Windows.Web.Http). 我现在正在使用(Windows.Web.Http)中的HttpClient。

Here is the fixed code: 这是固定代码:

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

    }

}

Hope this will help someone out there ;) 希望这会对外面的人有所帮助;)

thank you all 谢谢你们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM