C# 具有进度值的异步下载算法

C# 具有进度值的异步下载算法,c#,asynchronous,windows-runtime,windows-store-apps,C#,Asynchronous,Windows Runtime,Windows Store Apps,我为我的WinRT应用程序制作了简单的算法。具有类webresponse流的。我需要使用“ProgressChanged”事件异步下载文件。以下是我的方法: public async void DownloadFileAsync(string uri, StorageFile path) { var request = WebRequest.CreateHttp(uri); var response = await request.GetResponseAsync

我为我的WinRT应用程序制作了简单的算法。具有类webresponse流的。我需要使用“ProgressChanged”事件异步下载文件。以下是我的方法:

public async void DownloadFileAsync(string uri, StorageFile path)
{
        var request = WebRequest.CreateHttp(uri);
        var response = await request.GetResponseAsync();
        if (response != null)
        {
            long totalBytes = response.ContentLength;
            long writedBytes = 0;
            using(var webStream = response.GetResponseStream())
            using (IRandomAccessStream stream = await path.OpenAsync(FileAccessMode.ReadWrite))
            using (DataWriter dataWriter = new DataWriter(stream))
            {
                await Task.Run(() =>
                {
                    int b;
                    while ((b = webStream.ReadByte()) != -1)
                    {
                        dataWriter.WriteByte((byte)b);
                        writedBytes++;
                        if (writedBytes % (totalBytes / 100) == 0)
                            OnProgressChanged(new ProgressEventArgs(writedBytes / (totalBytes / 100)));
                    }
                });
                await dataWriter.StoreAsync();
                OnDownloadComplete(new EventArgs());
            }
        }
}
ProgressEventArgs代码:

public class ProgressEventArgs : EventArgs
{
    public ProgressEventArgs(double percentage)
    {
        Percentage = percentage;
    }
    public double Percentage { get; set; }
}

这是有效的。但我认为它应该更快。顺序字节读取太慢。我怎样才能使它更快。我是初学者。请提供帮助。

逐字节读取和写入大量数据可能会降低速度,下载1MB文件时将有数百万个方法调用。您应该使用缓冲区来读取数据块:

...
long totalBytesRead = 0;

// Allocate a 4KB buffer for each read/write    
byte[] buffer = new byte[4 * 1024];
int bytesRead;

// Read up to 4KB of data, check if any data read
while ((bytesRead = webStream.Read(buffer, 0, buffer.Length)) > 0) {
   // Write the 4KB (or less) buffer
   dataWriter.WriteBuffer(buffer.AsBuffer(0, bytesRead));
   totalBytesRead += bytesRead;

   // TODO: Report progresss
}    
....

最佳的缓冲区大小取决于许多因素,4KB的缓冲区应该可以。您可以获得更多信息。

逐字节读取和写入大量数据可能会降低速度,下载1MB文件时会有数百万个方法调用。您应该使用缓冲区来读取数据块:

...
long totalBytesRead = 0;

// Allocate a 4KB buffer for each read/write    
byte[] buffer = new byte[4 * 1024];
int bytesRead;

// Read up to 4KB of data, check if any data read
while ((bytesRead = webStream.Read(buffer, 0, buffer.Length)) > 0) {
   // Write the 4KB (or less) buffer
   dataWriter.WriteBuffer(buffer.AsBuffer(0, bytesRead));
   totalBytesRead += bytesRead;

   // TODO: Report progresss
}    
....

最佳的缓冲区大小取决于许多因素,4KB的缓冲区应该可以。您可以获得更多信息。

我查看了您的代码,发现您读取字节的方式可能会导致下载速度变慢,我建议您使用class,因为它速度更快,可以处理视频、音乐和图像等大量资源。
我做了一个演示,希望能对你有所帮助

Xaml部分:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <Button Content="Download File" Click="DownloadFile"/>
</Grid>
我已经测试过了,它是有效的。有关更多信息,您也可以参考


致以最诚挚的问候

我查看了您的代码,发现您读取字节的方式可能会导致下载速度变慢,我建议您使用class,因为它速度更快,可以处理视频、音乐和图像等大量资源。
我做了一个演示,希望能对你有所帮助

Xaml部分:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   <Button Content="Download File" Click="DownloadFile"/>
</Grid>
我已经测试过了,它是有效的。有关更多信息,您也可以参考


致以最诚挚的问候

您是初学者这一事实无关紧要,所以我们不在乎。也许你只是有一个缓慢的网络?到底什么东西慢?下载?文件读取?你能指一下速度慢的特定零件/生产线吗?整个方法是否运行缓慢?在while块中读取流。我认为,这不是一个好的解决方案。我错了吗?你是初学者这一事实无关紧要,所以我们不在乎。也许你只是有一个缓慢的网络?到底什么东西慢?下载?文件读取?你能指一下速度慢的特定零件/生产线吗?整个方法是否运行缓慢?在while块中读取流。我认为,这不是一个好的解决方案。我错了吗?后台下载API太乱了。除非您需要后台下载,否则我建议不要使用它。后台下载API太乱了。我建议不要使用它,除非你需要后台下载。