一个进度条与许多webclients

时间:2012-01-25 04:12:07

标签: c# progress-bar webclient

                    foreach (string line in textBox3.Lines)
                    {
                        int pos = line.IndexOf("?v=");
                        string videoid = line.Substring(pos + 3, 11);
                        GetFile(videoid);
                    }

        GetFile() {
        ...code

        WebClient webClient = new WebClient();
        webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
        webClient.DownloadFileAsync(new Uri(fileRequest), @textBox2.Text + @"\" + title + ".mp3");
    }

    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }

问题是如何使用一个进度条和许多Web客户端?这种情况不起作用,因为每个客户都在更新它自己的条形图并且它变得疯狂,那么正确的方法是什么? PS。我不能只使用一个WebClient,我之前会为每个文件发出请求。

1 个答案:

答案 0 :(得分:1)

我想你可以这样做:

public class WebClientProgressManager : INotifyPropertyChanged
        {
            private readonly Dictionary<WebClient,int> _clients = new Dictionary<WebClient, int>();
            private const string TotalProgressPropertyName = "TotalProgress";
            public void Add(WebClient client)
            {
                if (client == null)
                    throw new ArgumentNullException("client");
                if (_clients.ContainsKey(client)) return;

                client.DownloadProgressChanged += (s, e) =>
                                                      {
                                                          if (e.ProgressPercentage == 100)
                                                          {
                                                              _clients.Remove((WebClient)s);
                                                          }
                                                          RaisePropertyChanged(TotalProgressPropertyName);
                                                      };
                _clients.Add(client,0);

            }

            private void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged.Invoke(this,new PropertyChangedEventArgs(propertyName));
                }
            }

            public int TotalProgress
            {

                get
                {
                    if (_clients.Count == 0) return 100; //need something here to prevent divide-by-zero 
                    int progress = _clients.Sum(client => client.Value);
                    return progress/_clients.Count;
                }
            }

            #region Implementation of INotifyPropertyChanged

            public event PropertyChangedEventHandler PropertyChanged;

            #endregion
        }