【问题标题】:C# Multiple progress bars for multiple file downloadsC# 多个文件下载的多个进度条
【发布时间】:2013-05-01 06:43:25
【问题描述】:

我正在编写一个用于上传和下载文件的 C# 应用程序。下载使用 WebClient 对象及其DownloadAsycDownload 方法。下载适用于多个文件。它可以下载我想要的尽可能多的文件。

我的问题是我无法在动态添加到表单flowlayout control 的不同进度条中显示所有文件的进度。

这是我的代码:

public ProgressBar[] bar;
public int countBar=0;

...

    bar[countBar] = new ProgressBar();
    flowLayoutPanel1.Controls.Add(bar[countBar]);
    countBar++;

    request.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownoadInProgress);
    request.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted);
    request.DownloadFileAsync(new Uri(this.uri), localPath);

    byte[] fileData = request.DownloadData(this.uri);
    FileStream file = File.Create(localPath);
    file.Write(fileData, 0, fileData.Length);
    file.Close();
}

public void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    flowLayoutPanel1.Controls.Remove(bar[countBar]);
    countBar--;
    MessageBox.Show("Download Completed");
}

public void DownoadInProgress(object sender, DownloadProgressChangedEventArgs e)
{
    bar[countBar].Maximum = total_bytes;
    bar[countBar].Value = (int)e.BytesReceived;                
}

【问题讨论】:

    标签: c# progress-bar webclient


    【解决方案1】:

    您正在使用计数来索引进度条,但是一旦完成 - 您删除最后一个,您确实应该删除与文件关联的那个。

    在这种情况下,我建议使用Dictionary<WebClient, ProgressBar>(可能不是WebCliet - 应该是事件中sender 的类型)。

    ...
    var progBar = new ProgressBar();
    progBar.Maximum = 100;
    flowLayoutPanel1.Controls.Add(progBar);
    
    request.DownloadProgressChanged += DownoadInProgress;
    request.DownloadFileCompleted += DownloadFileCompleted;
    request.DownloadFileAsync(new Uri(this.uri), localPath);
    
    dic.Add(request, progBar);
    
    // You shouldn't download the file synchronously as well!
    // You're already downloading it asynchronously.
    
    // byte[] fileData = request.DownloadData(this.uri);
    // FileStream file = File.Create(localPath);
    // file.Write(fileData, 0, fileData.Length);
    // file.Close();
    

    然后,您可以完全删除countBar,并拥有新方法:

    public void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        // Can remove (WebClient) cast, if dictionary is <object, ProgressBar>
        var request = (WebClient)sender;
        flowLayoutPanel1.Controls.Remove(dic[request]);
        dic.Remove(request);
        MessageBox.Show("Download Completed");
    }
    
    public void DownoadInProgress(object sender, DownloadProgressChangedEventArgs e)
    {
        var progBar = dic[(WebClient)sender];
        progBar.Value = e.ProgressPercentage;                
    }
    

    【讨论】:

    • 谢谢,这真的很有帮助。
    • 如果这对您完全有帮助,请标记为已接受的答案。否则,让我知道缺少什么。
    • 我正在尝试从另一个类添加组件。无法在运行时将进度条添加到表单中。我发布的这些方法在另一个类中。
    • 没有错误。但不会在运行时添加进度条。单击按钮时应添加进度条。
    • 谢谢。如果您有一些想法,我已经在这里发布了链接stackoverflow.com/questions/16338447/…
    【解决方案2】:

    我会在 lambdas 中使用类似的东西,更简洁一点,字典中不需要:

    var webClient = new WebClient();
    
    var pb = new ProgressBar();
    pb.Maximum = 100;
    flowLayoutPanel1.Controls.Add(pb);
    
    webClient.DownloadProgressChanged += (o, args) =>
    {
        pb.Value = args.ProgressPercentage;
    };
    
    webClient.DownloadFileCompleted += (o, args) =>
    {
        flowLayoutPanel1.Controls.Remove(pb);
    };
    
    webClient.DownloadFileAsync(new Uri(this.uri), localPath);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 1970-01-01
      • 2022-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-11-21
      相关资源
      最近更新 更多