C# 我的问题是关于处理多个背景工人和多个progressbar
我的主要问题是,当我为每个请求在flowLayoutPanel1上动态添加一个progressbar时,如何从BackgroundWorker1\u ProgressChanged事件中增加右progressbar值 当用户单击开始按钮时,我将调用后台工作程序的RunWorkerAsync函数……这很好。在这里,我正在编写一个示例代码,并试图说明我的问题 我的表单有一个文本框、一个按钮和一个flowLayoutPanel1,FlowDirection自上而下 当用户在文本框中输入任何url并单击开始按钮时,我将使用BackGroundWorker开始文件下载,并在flowLayoutPanel1上动态添加一个进度条。每次可下载10个文件。所以当用户一个接一个地输入十个url并点击提交按钮时,十个文件将在后台下载 我的问题是如何从backgroundWorker1\u ProgressChanged事件中正确增加10个进度条进度。另一个问题是,当任何文件下载完成时,为其创建的进度条将从面板中删除 这是我的全部代码。请看一看,并告诉我需要做什么来完成我的任务。如果有人看到我的代码中存在死锁可能出现的问题,那么也请指导我如何避免死锁。这是我的密码C# 我的问题是关于处理多个背景工人和多个progressbar,c#,winforms,progress-bar,backgroundworker,C#,Winforms,Progress Bar,Backgroundworker,我的主要问题是,当我为每个请求在flowLayoutPanel1上动态添加一个progressbar时,如何从BackgroundWorker1\u ProgressChanged事件中增加右progressbar值 当用户单击开始按钮时,我将调用后台工作程序的RunWorkerAsync函数……这很好。在这里,我正在编写一个示例代码,并试图说明我的问题 我的表单有一个文本框、一个按钮和一个flowLayoutPanel1,FlowDirection自上而下 当用户在文本框中输入任何url并单击
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);