打开一个新线程以在GUI类中工作

时间:2013-01-28 22:05:36

标签: c# multithreading forms

我遇到了如何解决以下问题的问题。

我有一个类,它允许我动态更新并在表单上显示图形。为了更新图的值,我在表的类中有一个方法。我传入值以使用此方法更新图形。以下是我想要做的一个高级示例:

  

班级GUICLass:表格{

     

//这里绘制图表等代码

     

public updategraphWithNewValue(double value){

 // Code to update the graph
     

}

     

}

我的其他课程如下:

  

class ValueProviderForGraph {

     

GUIClass graphForm = new GUIClass();

     

public calculateValuesAndPlot(){

     

for(int i = 0; i< 4000; i ++){

  graphForm.updategraphWithNewValue(i);

  graphForm.update();
     

}

     

}

     

}

现在我从上面得到的问题是,在执行此操作时表单会冻结。我怎么能绕过这个,任何帮助或建议将不胜感激。我希望这个高级别的例子有足够的信息,如果没有,请告诉我,我会尝试更好地解释自己。 感谢。

3 个答案:

答案 0 :(得分:5)

使用BackgroundWorker。它面向事件的界面可以帮助您快速启动并运行。

答案 1 :(得分:2)

您只能从最初创建控件的线程更新表单的控件。

如果您尝试从其他线程更新它,则必须封送该调用。网上有很多方法。我个人最喜欢的(对于WinForms)如下:

https://stackoverflow.com/a/709846/141172

<强>更新

在@StenPetrov的催促下重新阅读你的问题之后,我怀疑你毕竟没有交叉线程问题,但UI线程在更新图形时根本不处理消息(这会导致在手术期间冻结。)

如果UI线程忙于更新图表,您将获得该行为。但是,看起来您导致图形执行不必要的更新3999次。尝试移动线

graphForm.update();
for 循环之外的

虽然我不确切知道你的图形控件是如何工作的,但我怀疑对update()的调用导致整个图形被重新渲染。只有在添加了所有新数据点之后,才应该这样做。

答案 2 :(得分:0)

您是否需要经常更新用户界面?

如果您不必经常更新UI,例如加载大图以供查看,那么BackgroundWorker将会这样做。

如果您需要经常更新UI,您必须(a)使您的图形计算独立于UI,(b)在单独的线程中运行图形计算,(c)在计算更新后使用Form.Invoke(。 ..)更新UI