以下代码给出了以下错误。我想我需要“InvokeRequired”。但我不明白我该怎么用?
错误:跨线程操作无效:控制'statusBar1'从其创建的线程以外的线程访问。
代码:
public void CalculateGeneration(int nPopulation, int nGeneration)
{
int _previousFitness = 0;
Population TestPopulation = new Population();
for (int i = 0; i < nGeneration; i++)
{
if (_threadFlag)
break;
TestPopulation.NextGeneration();
Genome g = TestPopulation.GetHighestScoreGenome();
if (i % 100 == 0)
{
Console.WriteLine("Generation #{0}", i);
if ( ToPercent(g.CurrentFitness) != _previousFitness)
{
Console.WriteLine(g.ToString());
_gene = g;
statusBar1.Text = String.Format("Current Fitness = {0}", g.CurrentFitness.ToString("0.00"));
this.Text = String.Format("Sudoko Grid - Generation {0}", i);
Invalidate();
_previousFitness = ToPercent(g.CurrentFitness);
}
if (g.CurrentFitness > .9999)
{
Console.WriteLine("Final Solution at Generation {0}", i);
statusBar1.Text = "Finished";
Console.WriteLine(g.ToString());
break;
}
}
}
}
答案 0 :(得分:2)
最简单的可重用性是添加一个辅助函数,如:
void setstatus(string txt)
{
Action set = () => statusBar1.Text = txt;
statusBar1.Invoke(set);
}
或者首先使用invokerequired检查:
delegate void settextdelegate(string txt);
void setstatus(string txt)
{
if (statusBar1.InvokeRequired)
statusBar1.Invoke(new settextdelegate(setstatus), txt);
else
statusBar1.Text = txt;
}
无论哪种方式,状态都可以设置为
setstatus("Finished");
为了完整起见,我应该补充一点,更好的办法是将计算逻辑与表单分开,并从计算功能中提升可以由表单处理的状态,但这可能完全超出范围。< / p>