Xamarin.iOS 中的线程处理
Xamarin.iOS 运行时使开发人员能够访问 .NET 线程 API,无论是使用线程 (System.Threading.Thread, System.Threading.ThreadPool
) 时显式访问,还是使用异步委托模式或 BeginXXX 方法时隐式访问,以及支持任务并行库的全系列 API。
Xamarin 强烈建议使用任务并行库 (TPL) 来生成应用程序,原因如下:
- 默认的 TPL 计划程序会将任务执行委托给线程池,而线程池又会在进程发生时动态增加所需的线程数量,同时避免出现过多线程最终争用 CPU 时间的情况。
- 从 TPL 任务的角度考虑操作会更容易。 可以轻松地操作任务、安排任务、序列化任务的执行或使用一组丰富的 API 并行启动任务。
- 它是使用新的 C# 异步语言扩展进行编程的基础。
线程池将根据系统上可用的 CPU 核心数、系统负载和应用程序需求,根据需要缓慢增加线程数。 可以通过调用 System.Threading.ThreadPool
中的方法或使用默认 System.Threading.Tasks.TaskScheduler
(并行框架的一部分)来使用此线程池。
通常,开发人员在需要创建响应式应用程序并且不想阻止主 UI 运行循环时使用线程。
开发响应式应用程序
对 UI 元素的访问应仅限于运行应用程序主循环的同一线程。 如果要从线程更改主 UI,则应该使用 NSObject.InvokeOnMainThread 对代码进行排队,如下所示:
MyThreadedRoutine ()
{
var result = DoComputation ();
// we want to update an object that is managed by the main
// thread; To do so, we need to ensure that we only access
// this from the main thread:
InvokeOnMainThread (delegate {
label.Text = "The result is: " + result;
});
}
上述代码在主线程的上下文中调用委托内的代码,而不会导致任何可能导致应用程序崩溃的争用条件。
线程处理和垃圾回收
在执行过程中,Objective-C 运行时将创建和释放对象。 如果将对象标记为“自动释放”,Objective-C 运行时会将这些对象释放到线程的当前 NSAutoReleasePool
。 Xamarin.iOS 为 System.Threading.ThreadPool
中的每个线程和主线程创建一个 NSAutoRelease
池。 这通过扩展涵盖了使用 System.Threading.Tasks 中的默认 TaskScheduler 创建的任何线程。
如果使用 System.Threading
创建自己的线程,则必须提供自己的 NSAutoRelease
池以防止数据泄漏。 为此,只需将线程包装在以下代码片段中:
void MyThreadStart (object arg)
{
using (var ns = new NSAutoReleasePool ()){
// Your code goes here.
}
}
注意:从 Xamarin.iOS 5.2 开始,系统会自动为你提供 NSAutoReleasePool
,因此你不必再自己提供。