C# Backgroundworker ReportProgress只触发一次?
是什么原因导致我的C# Backgroundworker ReportProgress只触发一次?,c#,progress-bar,backgroundworker,C#,Progress Bar,Backgroundworker,是什么原因导致我的Processbar1和ReportProgress仅触发一次 我第一次单击按钮时,一切都按预期进行。所有进一步的点击,除了ProgressBar1,所有的东西都还在工作 我可以在调试器中看到progressBar1.Value在第一次运行时获得预期值,所有后续运行progressBar1.Value始终包含“0” 最奇怪的是,它运行foreach循环,执行所有内容,甚至b.ReportProgress(i*100/x)中的值都正确,但没有成功的progressbar。 i=当
Processbar1
和ReportProgress
仅触发一次
我第一次单击按钮时,一切都按预期进行。所有进一步的点击,除了ProgressBar1
,所有的东西都还在工作
我可以在调试器中看到progressBar1.Value
在第一次运行时获得预期值,所有后续运行progressBar1.Value
始终包含“0”
最奇怪的是,它运行foreach循环
,执行所有内容,甚至b.ReportProgress(i*100/x)
中的值都正确,但没有成功的progressbar。i=当前环路计数
x=循环总数
. 以下是我的代码片段:
BackgroundWorker b = new BackgroundWorker();
public Form()
{
InitializeComponent();
b.WorkerReportsProgress = true;
b.DoWork += new DoWorkEventHandler(b_DoWork);
b.RunWorkerCompleted += new RunWorkerCompletedEventHandler(b_RunWorkerCompleted);
b.ProgressChanged += new ProgressChangedEventHandler(b_ProgressChanged);
}
void b_DoWork(object sender, DoWorkEventArgs e)
{
int i = 0;
int x = xxx.MaxValue;
foreach (var item in collection)
{
//... somecode ...(item);
b.ReportProgress(i * 100 / x);
i++;
}
//... somecode
e.Result = dt;
}
void b_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
void b_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
GridView.DataSource = e.Result;
GridView.Update();
}
private void button1_Click(object sender, EventArgs e)
{
b.RunWorkerAsync();
}
编辑:
private void btnClearGrid_Click(object sender, EventArgs e)
{
dt.Clear();
GridView.DataSource = dt;
GridView.Update();
}
我发现了问题。问题是,在运行Backgroundworker之前,我试图清除Gridview,这个
btnClearGrid
-单击事件包含Gridview.DataSource=dt代码>将一个额外的数据源绑定到网格(我认为是这样),而不是清除网格
private void btnClearGrid_Click(object sender, EventArgs e)
{
dt.Clear();
GridView.DataSource = null;
}
尝试在两次单击之间重置进度条:
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Value = 0;
b.RunWorkerAsync();
}
我遇到了这个问题,这和更新ProgressBar的速度有关,我通过在DoWork方法中添加显式线程睡眠来解决这个问题。即:
b.ReportProgress(i * 100 / x);
Thread.Sleep(50);
(同时检查这部分中的50毫秒与正在完成的实际工作相比不是太多;如果是报告进度和睡眠,则每隔一段时间才报告一次)在int x=xxx.MaxValue之后x
的值是多少代码>语句?你的解释告诉我它是循环计数的总和,但我似乎不是。从你上面的问题描述来看,I++
只在第一次运行时发生。我们可能需要查看更多的代码。x=只是一个文件中的总行数(实际上=129886),我还将其用作foreach循环的集合。顺便说一句,可能有任何价值。但我发现progressBar正在工作,只是第二次运行时速度非常慢,然后按钮1_Click-Event
。ReportProgress调用是在由foreach(集合中的var项)控制的外观内进行的;您尚未提供定义集合的代码。你可能忽略了这个循环中的相关代码。你不应该在做任何事情之前检查一下BackgroundWorker.IsBusy
,这样如果BackgroundWorker
已经在运行,你就不会得到InvalidOperationException
?是的@Bob,你完全正确,我会立即添加检查。感谢you@MrMAG在这两条语句周围环绕检查,如果使用此选项,则不希望在每次单击时重置进度条。