是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