2011-10-05 46 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