是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標誌並調用 方法來避免交叉線程問題。
這是否意味着它是純粹的巧合,它沒有使用InvokeOnMainThread而沒有NSAutoReleasePool?因爲我沒有看到任何問題,但它不適用於正常的線程。 – Krumelur