2008-09-23 60 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將會響應。如果用戶做出某種不需要繼續繪製的操作,只需中止該線程。