我试图实现一个backgroudworker,但是在第二个帖子中不起作用,表单仍然在loking,而且e无法调用我的按钮2的事件,有人告诉我它为什么会发生?
我的代码:
public Form1()
{
InitializeComponent();
backgroundWorker1.DoWork +=
new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged +=
new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.WorkerReportsProgress = true;
}
void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Work is done");
}
void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ThreadProc();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
void ThreadProc()
{
//simulate work
for (int i = 0; i < 100000; ++i)
{
int total = i / 1000;
backgroundWorker1.ReportProgress(total);
}
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Another thread");
}
TKS;
答案 0 :(得分:4)
看起来您可能会以非常快的速度向表单报告进度,这会导致表单被锁定。
尝试更改ThreadProc方法,仅用于演示目的:
void ThreadProc ()
{
//simulate work
for ( int i = 0; i < 100000; ++i )
{
Thread.Sleep( 1 ); // this should allow the form to breath a little :)
int total = i / 1000;
backgroundWorker1.ReportProgress( total );
}
}
答案 1 :(得分:1)
我认为,因为你通过让你的线程报告进度100000次来不断更新你的UI线程,你的UI线程太忙了,不能接受来自Button 2的click事件。我会显着降低报告的数量,看看是否这样有任何影响。
由于ProgressBar.Value是一个int,因此不应该有区别:
for (int i = 0; i < 100; i++)
{
backgroundWorker1.ReportProgress(i);
}
答案 2 :(得分:0)
对于初学者,我可以说后台工作者将在ThreadPool
分配的另一个线程上。尽管如此,仍然可以锁定您的UI,因为当您调用ProgressChanged
或RunWorkerCompleted
事件时,它们会被编组回UI线程。只有DoWork
事件适用于另一个ThreadPool
主题。
如果您在UI线程上不,则无法访问UI元素,例如按钮2,而无需额外的工作。要从其他线程访问UI元素,您需要使用Control.Invoke
将调用封送回UI线程。