在我的应用程序中,我有一个由进度条和文件名组成的队列下载列表。当用户单击按钮时,文件名和进度条被实例化并添加到队列中。文件一次异步下载一个。我想要做的是将等待下载的文件的所有进度条保持为黄色,然后在下载时变为绿色,然后在完成时变为蓝色。如果我CheckForIllegalCrossThreadCalls = false;
在自定义进度条的构造函数中,它目前可以工作。我想看看是否有办法对进度条进行线程安全的更改。
我将每个队列项目设置为一个对象。当按下按钮并在队列项构造函数中创建进度条时,队列项对象是从主表单代码(Form1.cs)创建的,这可能是我的问题开始的地方。下载是通过队列项目对象中的函数开始的。
队列项目片段
public class QueueItem
{
public bool inProgress;
public QueueBar bar;
public QueueItem(args)
{
bar = new QueueBar();
inProgress = false;
// handle arguments
}
public void Download()
{
// process info
WebClient client = new WebClient();
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileAsync(url, @savePath);
}
private long lastByte = 0;
private long newByte = 0;
private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
percentValue = e.ProgressPercentage;
bar.Value = e.ProgressPercentage;
newByte = e.BytesReceived;
}
private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
// change bar color
bar.Value = 100;
}
}
队列栏片段
public class QueueBar : ProgressBar
{
// variables
public QueueBar()
{
this.SetStyle(ControlStyles.UserPaint, true);
// initialize variables
}
// function to change text properties
// function to change color
protected override void OnPaint(PaintEventArgs e)
{
// painting
}
}
主要功能片段
public partial class Form1 : Form
{
private List<QueueItem> qItems;
private BackgroundWorker queue;
private void button_Click(object sender, EventArgs e)
{
// basic gist of it
qItems.Add(new QueueItem(args));
Label tmpLabel = new Label();
tmpLabel.Text = filename;
tmpLabel.Dock = DockStyle.Bottm;
splitContainerQueue.Panel2.Controls.Add(tmpLabel);
splitContainerQueue.Panel2.Controls.Add(qItems[qItems.Count - 1].bar);
if (!queue.IsBusy) { queue.RunWorkerAsync(); }
}
private void queue_DoWork(object sender, DoWorkEventArgs e)
{
while (qItems.Count > 0)
{
if (!qItems[0].inProgress && qItems[0].percentValue == 0)
{
qItems[0].inProgress = true;
qItems[0].Download();
}
// else if statements
}
}
我也只是尝试创建一个后台工作人员来创建队列项并异步添加控件,但这不起作用,因为拆分容器是在不同的线程上创建的。