2011-10-05 53 views
2

我使用System.ComponentModel.BackgroundWorker執行一些長時間運行的任務,最終會更新一些UI元素。MonoTouch中的System.ComponentModel.BackgroundWorker - 正確的用法?

對此問題:

  • BackgroundWorker.RunWorkerCompleted的UI主線程上執行,或者在一個單獨的線程?或者有不同的問題:我是否需要在using(NSAutoReleasePool)中嵌入我的代碼,並且必須使用InvokeOnMainThread()才能使用普通線程?
  • 我必須在BackgroundWorker.DoWork代表內使用NSAutoReleasePool嗎?

回答

1

BackgroundComponentWorker尚未適應上的MonoTouch或單聲道工作Android的,所以它不會做什麼特別的UI線程。

所引發的任何事件都不會在UI線程中產生,因此您需要手動將這些事件包裝在BeginInvokeOnMainThread中。

+0

這是否意味着它是純粹的巧合,它沒有使用InvokeOnMainThread而沒有NSAutoReleasePool?因爲我沒有看到任何問題,但它不適用於正常的線程。 – Krumelur

1

是BackgroundWorker.RunWorkerCompleted在UI主線程, 或在一個單獨的線程中執行?或者有不同的問題:我是否必須在使用(NSAutoReleasePool)中嵌入我的 代碼,並且必須像使用普通線程時那樣使用InvokeOnMainThread() ?

BackgroundWorker.RunWorkerCompleted在UI線程上運行,前提是工作人員是在該UI線程上創建的,並且您在UI線程上調用了RunWorkerAsync。

更確切地說,BackgroundWorker使用SynchronizationContext.Current在UI線程上運行代碼。 WPF,Silverlight,WinForms,Asp.NET在初始化時都會安裝SynchronizationContext(例如System.Windows.Forms.WindowsFormsSynchronizationContext)。

如果您的UI框架是一個好的.NET公民,它將安裝自己的同步上下文,並且BackgroundWorker將在UI線程上引發事件。

我是否必須在BackgroundWorker.DoWork 委託內使用NSAutoReleasePool?

我可以告訴你,DoWork在後臺線程上運行。如果您想操作該後臺線程上的UI元素,則需要按照UI框架的規則進行操作。

this thread in the Mono mailing list

  • 你不必把一個NSAutoreleasePool在DoWork的處理 除非你操縱Cocoa類
  • 你必須把一個NSAutoreleasePool在ProgressChanged處理 以避免內存泄漏。似乎正在運行的線程不是主要的 之一。
  • 您必須在RunWorkerCompleted 處理程序中放置NSAutoreleasePool以避免內存泄漏。似乎正在運行的線程不是主要的 。
  • 雖然它們不在主線程上運行(讀取: 危險),但您可以直接在 處理程序上修改標記或進度指示符值。最好的方法是使用InvokeRequired標誌並調用 方法來避免交叉線程問題。
+0

第一部分的好建議。然而,鏈接的電子郵件來自與MonoTouch不同的monobjc郵件列表。 – poupou