2008-09-23 16 views
1

我正在编写一个在PDA上显示地图的.NET Compact Framework应用程序。如何更新不同线程中的组件? .NET CF

我已经创建了一个ad hoc组件,它使用构成大图的几个这些组件来绘制它自己的整个地图。我这样做是为了避免在一个步骤中绘制整个地图的延迟。

我想要知道的是在自己的线程中绘制这些片断,因此地图看起来像一个单一的实体一样成长,并且(更重要的是)避免冻结其余的用户界面。

知道地图的每一部分都在其onPaint方法中绘制。我的想法是,以某种方式告诉系统“请在线程中执行此代码”。

喜欢的东西:

protected override void OnPaint(PaintEventArgs e) 
    { 
     // <code to be executed in a thread> 
     e.Graphics.paintTHis(); 
     e.Graphics.paintThat(); 
     whateverItTakesToPaintThisPieceOfTheMap(); 
     // </code to be executed in a thread> 
    } 

你知道如何做到这一点?或者我的方法是错误的?

谢谢你的时间!

回答

3

该方法是错误的。更新ui的代码必须在ui线程上运行。如果您从另一个线程更新ui,您会得到一个异常。

0

我建议你有一些从底层线程到主UI线程的消息传递系统。

这种方式主UI线程进行所有更改并从底层线程触发。还要确保你可以用这些消息发送一些数据,以防你想发送一些复杂的信息回到主UI线程。

1

为了调用从另一个线程更新UI的函数,请使用Form的Invoke函数。

这里是一个很好的参考

http://weblogs.asp.net/justin_rogers/articles/126345.aspx

编辑:在评论中指出的BeginInvoke会更好,如果你想调用代码不等待UI线程。

+0

调用将调用放置在原始线程上 - 这违背了目的。 – ima 2008-09-23 14:14:26

1

在后台线程的内存中绘制地图,然后在准备好时渲染(在UI线程中)该栅格图像以供屏幕显示。如果可能,请使用BufferedGraphics,否则使用GDI。

1

如果渲染地图非常耗时,并且您不想冻结GUI线程(使您的应用程序无响应),则可以将屏幕分割为单元格。使用后台线程将单元格渲染为位图,使用Invoke通知GUI线程绘制完成的单元格,当invoke返回时,让线程继续处理下一个单元格。

您需要直接绘制到控件上(不在Paint()内部),或者需要调用invalidateRect并有一些逻辑来确保计算出的图像与系统要绘制的图像相匹配。

这将使您的图像逐渐显示,并且您的UI将会响应。如果用户做出某种不需要继续绘制的操作,只需中止该线程。

相关问题