如何使用网络客户端计算并显示下载速度?

Dan*_*Lip 2 c# unity-game-engine

目标是在下载时计算并在 label4.Text 上显示下载速度。

private void Download()
        {
            using (var client = new WebClient())
            {
                client.DownloadFileCompleted += (s, e) => label1.Text = "Download file completed.";
                client.DownloadProgressChanged += (s, e) => progressBar1.Value = e.ProgressPercentage;
                client.DownloadProgressChanged += (s, e) => label2.Text = FormatBytes(e.BytesReceived);
                client.DownloadProgressChanged += (s, e) => label4.Text = e.
                client.DownloadProgressChanged += (s, e) =>
                {
                    label3.Text = "%" + e.ProgressPercentage.ToString();
                    label3.Left = Math.Min(
                        (int)(progressBar1.Left + e.ProgressPercentage / 100f * progressBar1.Width),
                        progressBar1.Width - label3.Width
                    );                   
                };

                client.DownloadFileAsync(new Uri("https://speed.hetzner.de/10GB.bin"), @"d:\10GB.bin");
            }
        } 
Run Code Online (Sandbox Code Playgroud)

在带有 label4.Text 的行我想显示速度。

client.DownloadProgressChanged += (s, e) => label4.Text = e.
Run Code Online (Sandbox Code Playgroud)

Aud*_*ive 5

正如@AKX建议的那样,Stopwatch类可以帮助您计算下载文件时每秒接收的字节数。

在类范围中创建一个字段(基于 WPF 应用程序的示例):

public partial class MainWindow : Window 
{
    private readonly System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
}
Run Code Online (Sandbox Code Playgroud)

初始化时WebClient(最简单的方法),创建 2 个处理程序:for WebClient.DownloadProgressChangedevent 和 for WebClient.DownloadFileCompletedevent。然后在打电话之前WebClient.DownloadFileAsync()打电话stopwatch.Start()开始测量时间。

using (System.Net.WebClient wc = new System.Net.WebClient())
{
    wc.DownloadProgressChanged += OnDownloadProgressChange;
    wc.DownloadFileCompleted += OnDownloadFileComplete;

    stopwatch.Start(); // Start the Stopwatch
    wc.DownloadFileAsync(downloadLink, fileName); // Run file download asynchroniously
}
Run Code Online (Sandbox Code Playgroud)

DownloadProgressChanged事件处理程序中,您可以组合DownloadProgressChangedEventArgsBytesReceived属性和StopwatchElapsed.TotalSeconds属性来获取下载速度:

private void OnDownloadProgressChange(object sender, System.Net.DownloadProgressChangedEventArgs e)
{
    // Calculate progress values
    string downloadSpeed = string.Format("{0} MB/s", (e.BytesReceived / 1024.0 / 1024.0 / stopwatch.Elapsed.TotalSeconds).ToString("0.00"));
}
Run Code Online (Sandbox Code Playgroud)

我除以BytesReceived1024 两次,得到以 MB 为单位的值,而不是以字节为单位,但您可以根据需要进行选择。我还将结果值格式化为0.00(例如获得“1.23 MB/s”)。如果需要,您还可以DownloadProgressChangedEventArgs根据您的目的计算和格式化其他属性。

最后,在WebClient.DownloadFileCompleted事件处理程序中,您应该重置Stopwatch以停止它并重置其测量时间以进行其他新下载:

private void OnDownloadFileComplete(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
    stopwatch.Reset();
}
Run Code Online (Sandbox Code Playgroud)

完整版本可能如下所示(MainWindow.cs):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private readonly System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

    private void BtnDownloadFile_Click(object sender, RoutedEventArgs e)
    {
        Uri downloadLink = new Uri("https://speed.hetzner.de/100MB.bin");
        string fileName = "H:\\100MB.bin";

        btnDownloadFile.IsEnabled = false; // Disable to prevent multiple runs

        using (System.Net.WebClient wc = new System.Net.WebClient())
        {
            wc.DownloadProgressChanged += OnDownloadProgressChange;
            wc.DownloadFileCompleted += OnDownloadFileComplete;

            stopwatch.Start();
            wc.DownloadFileAsync(downloadLink, fileName);
        }
    }

    private void OnDownloadProgressChange(object sender, System.Net.DownloadProgressChangedEventArgs e)
    {
        // Calculate progress values
        string downloadProgress = e.ProgressPercentage + "%";
        string downloadSpeed = string.Format("{0} MB/s", (e.BytesReceived / 1024.0 / 1024.0 / stopwatch.Elapsed.TotalSeconds).ToString("0.00"));
        string downloadedMBs = Math.Round(e.BytesReceived / 1024.0 / 1024.0) + " MB";
        string totalMBs = Math.Round(e.TotalBytesToReceive / 1024.0 / 1024.0) + " MB";

        // Format progress string
        string progress = $"{downloadedMBs}/{totalMBs} ({downloadProgress}) @ {downloadSpeed}"; // 10 MB / 100 MB (10%) @ 1.23 MB/s

        // Set values to contols
        lblProgress.Content = progress;
        progBar.Value = e.ProgressPercentage;
    }

    private void OnDownloadFileComplete(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        lblProgress.Content = "Download complete!";
        stopwatch.Reset();
        btnDownloadFile.IsEnabled = true; // Restore arailability of download button
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML:

<Grid>
    <StackPanel HorizontalAlignment="Stretch" 
                VerticalAlignment="Center">
        <Label x:Name="lblProgress" 
               Content="Here would be progress text" 
               Margin="10,0,10,5" 
               HorizontalContentAlignment="Center"/>
        <ProgressBar x:Name="progBar" 
                     Height="20" 
                     Margin="10,0,10,5" />
        <Button x:Name="btnDownloadFile" 
                Content="Download file" 
                Width="175" 
                Height="32" 
                Click="BtnDownloadFile_Click"/>
    </StackPanel>
</Grid>
Run Code Online (Sandbox Code Playgroud)

看起来如何:

在此输入图像描述