如何更新不同线程中的组件? .NET CF

时间:2008-09-23 12:01:55

标签: .net multithreading graphics compact-framework

我正在编写一个.NET Compact Framework应用程序,它在PDA上显示地图。

我已经创建了一个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>
    }

你知道怎么做吗?或者我的做法完全错了?

谢谢你的时间!

5 个答案:

答案 0 :(得分:3)

方法错了。更新ui的代码必须在ui线程上运行。如果你从另一个线程更新ui,你会得到一个例外。

答案 1 :(得分:1)

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

这是一个很好的参考

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

编辑:正如评论中所指出的,如果你希望调用代码不要等待UI线程,那么BeginInvoke会更好。

答案 2 :(得分:1)

在后台线程中在内存中绘制地图,然后在准备好时(在UI线程中)将光栅图像渲染到屏幕。如果可能,请使用BufferedGraphics,否则使用GDI。

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:0)

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

这样,主UI线程进行所有更改并从底层线程触发。还要确保您可以使用这些消息发送一些数据,以防您想将一些复杂信息发送回主UI线程。

相关问题