MonoTouch 中的线程
在 MonoTouch 中, 可以使用标准的 .Net 线程 API , 既可以直接使用线程(System.Threading.Thread、System.Threading.ThreadPool), 也可以简介使用异步委托模式以及 BeginXXX 、 EndXXX 方法。
最好使用 Mono 的线程池, 这样,系统的开销增加的非常缓慢, 充分利用多核来平衡系统的负载以及程序的需求。 可以通过调用 System.Threading.ThreadPool 的方法或者使用默认的 System.Threading.Tasks.TaskScheduler (Parallel Framework 的一部分) 来使用线程池。
通常, 当开发者需要创建即时响应界面并且不希望阻塞主界面的程序时, 需要用到线程。
开发即时响应的应用
对界面元素的操作必须限制在运行主界面循环的线程, 如果需要线程中对界面做修改, 则必须使用 NSObject.InvokeOnMainThread 把代码添加到队列, 例如:
MyThreadedRoutine() { var result = DoComputation(); // 计算完成之后, 需要更新界面, 需要保证操作界面的代码一定是在主界面线程执行 InvokeOnMainThread(delegate { label.Text = "The result is: " + result; }); }
上面的委托中的代码会在主界面线程的上下文中执行, 没有任何竞争条件, 不会导致程序崩溃。
线程与垃圾回收
Objective-C 运行时会在执行的过程中创建和销毁对象, 如果对象被标记为 “auto-release” , Objective-C 运行时将会把这些对象放到线程当前的 NSAutoReleasePool 进行销毁。 MonoTouch 为主界面线程以及每个由 ThreadPool 创建的线程分配一个 NSAutoReleasePool, 当然也包括用默认 TaskScheduler 创建的 Task 。
如果需要创建自己的线程, 则必须也提供一个 NSAutoReleasePool 来防止内存泄漏, 如果要这样做的话, 用下面的代码包含你的代码即可:
void MyThreadStart(object arg) { using (var ns = new NSAutoReleasePool()) { // Your code goes here. } }
张志敏所有文章遵循创作共用版权协议,要求署名、非商业 、保持一致。在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处。
本博客已经迁移到 GitHub , 围观地址: https://beginor.github.io/