C# 我的问题是关于处理多个背景工人和多个progressbar

C# 我的问题是关于处理多个背景工人和多个progressbar,c#,winforms,progress-bar,backgroundworker,C#,Winforms,Progress Bar,Backgroundworker,我的主要问题是,当我为每个请求在flowLayoutPanel1上动态添加一个progressbar时,如何从BackgroundWorker1\u ProgressChanged事件中增加右progressbar值 当用户单击开始按钮时,我将调用后台工作程序的RunWorkerAsync函数……这很好。在这里,我正在编写一个示例代码,并试图说明我的问题 我的表单有一个文本框、一个按钮和一个flowLayoutPanel1,FlowDirection自上而下 当用户在文本框中输入任何url并单击

我的主要问题是,当我为每个请求在flowLayoutPanel1上动态添加一个progressbar时,如何从BackgroundWorker1\u ProgressChanged事件中增加右progressbar值

当用户单击开始按钮时,我将调用后台工作程序的RunWorkerAsync函数……这很好。在这里,我正在编写一个示例代码,并试图说明我的问题

我的表单有一个文本框、一个按钮和一个flowLayoutPanel1,FlowDirection自上而下

当用户在文本框中输入任何url并单击开始按钮时,我将使用BackGroundWorker开始文件下载,并在flowLayoutPanel1上动态添加一个进度条。每次可下载10个文件。所以当用户一个接一个地输入十个url并点击提交按钮时,十个文件将在后台下载

我的问题是如何从backgroundWorker1\u ProgressChanged事件中正确增加10个进度条进度。另一个问题是,当任何文件下载完成时,为其创建的进度条将从面板中删除

这是我的全部代码。请看一看,并告诉我需要做什么来完成我的任务。如果有人看到我的代码中存在死锁可能出现的问题,那么也请指导我如何避免死锁。这是我的密码

public partial class Form1 : Form
    {
        static int pbCounter = 1;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            ProgressBar pb = new ProgressBar();
            if (pbCounter <= 10)
            {
                pb.Width = txtUrl.Width;
                flowLayoutPanel1.Controls.Add(pb);
                pbCounter++;

                System.ComponentModel.BackgroundWorker backgroundWorker1 = new System.ComponentModel.BackgroundWorker();

                backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
                backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
                backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get the BackgroundWorker that raised this event.
            System.ComponentModel.BackgroundWorker worker = sender as System.ComponentModel.BackgroundWorker;

            // Assign the result of the computation
            // to the Result property of the DoWorkEventArgs
            // object. This is will be available to the  
            // RunWorkerCompleted eventhandler.
            //#e.Result = ComputeFibonacci((int)e.Argument, worker, e);
        }

        // This event handler deals with the results of the
        // background operation.
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // First, handle the case where an exception was thrown.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                //# "Canceled";
            }
            else
            {
                pbCounter--;
                // Finally, handle the case where the operation  
                // succeeded.
                //#resultLabel.Text = e.Result.ToString();
            }
        }

        // This event handler updates the progress bar.
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;
        }

    }
公共部分类表单1:表单
{
静态计数器=1;
公共表格1()
{
初始化组件();
}
私有void btnStart_单击(对象发送方,事件参数e)
{
ProgressBar pb=新的ProgressBar();

如果(pbCounter这是一种方法-

创建从BackgroundWorker继承的自己的类,添加ProgressBar类型的公共变量

每次动态添加BackgroundWorker和Progressbar时,将Progressbar对象传递给类

您的派生类-

public class MyBackgroundWorker : BackgroundWorker
{
    public ProgressBar pbProgress = null;

    public void BackgroundWorker()
    {
    }
}
按钮事件代码-

private void btnStart_Click(object sender, EventArgs e)
{
    ProgressBar pb = new ProgressBar();
    if (pbCounter <= 10)
    {
        pb.Width = txtUrl.Width;
        flowLayoutPanel1.Controls.Add(pb);
        pbCounter++;

        MyBackgroundWorker backgroundWorker1 = new MyBackgroundWorker();
        backgroundWorker1.pbProgress = pb;

        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

        backgroundWorker1.RunWorkerAsync();
    }
}

首先声明一个全局字典和一个GetInstance方法来访问表单实例

public partial class Form1 : Form
{
Dictionary<String, ProgressBar> progressBars = new Dictionary<String, ProgressBar>();

static Form1 _form1 = null;

static int pbCounter = 1;

public Form1()
{
    InitializeComponent();
    _form1 = this;
}

public static Form1 GetInstance() {
    return _form1;
}
在form.cs中创建一个函数,在该函数中可以传递progressbar,然后可以手动设置它的值

public void ProgessReport(ProgressBar pb, int value) 
        {
            if (pb.InvokeRequired) 
            {
                pb.Invoke(new MethodInvoker(delegate { ProgessReport(pb, value); }));
            } else 
            {
                pb.Value = value;
            }
        }
现在,从下载文件的地方,您只需调用

Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 10);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 20);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 100);

and when your second file downloads then

Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 10);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 20);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 100);

像这样..

您没有显示下载文件的位置…请共享该代码以下载文件不是问题,而是我想从backgroundWorker1\u ProgressChanged事件中捕获正确的进度条并增加其值。因为我的进度条是动态创建的,所以我如何确定需要捕获的进度条和看到我的答案了吗?你现在需要改变流程来解决这个问题,他现在可以跟踪哪个进度条需要增加,就好像有10个文件要下载,那么他就有10 pb了
progressBars.Add("file1", pb1);
progressBars.Add("file2", pb2);
progressBars.Add("file3", pb3);
progressBars.Add("file4", pb4);
public void ProgessReport(ProgressBar pb, int value) 
        {
            if (pb.InvokeRequired) 
            {
                pb.Invoke(new MethodInvoker(delegate { ProgessReport(pb, value); }));
            } else 
            {
                pb.Value = value;
            }
        }
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 10);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 20);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 100);

and when your second file downloads then

Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 10);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 20);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 100);