C#多个文件下载的多个进度条

时间:2013-05-01 06:43:26

标签: c# progress-bar webclient-download

我正在编写一个用于上传和下载文件的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;                
}

2 个答案:

答案 0 :(得分: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;                
}

答案 1 :(得分:1)

我会使用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);