MonoTouch 中的线程
在 MonoTouch 中, 可以使用标准的 .Net 线程 API , 既可以直接使用线程(System.Threading.Thread、System.Threading.ThreadPool), 也可以简介使用异步委托模式以及 BeginXXX 、 EndXXX 方法。
最好使用 Mono 的线程池, 这样,系统的开销增加的非常缓慢, 充分利用多核来平衡系统的负载以及程序的需求。 可以通过调用 System.Threading.ThreadPool 的方法或者使用默认的 System.Threading.Tasks.TaskScheduler (Parallel Framework 的一部分) 来使用线程池。
通常, 当开发者需要创建即时响应界面并且不希望阻塞主界面的程序时, 需要用到线程。
开发即时响应的应用
对界面元素的操作必须限制在运行主界面循环的线程, 如果需要线程中对界面做修改, 则必须使用 NSObject.InvokeOnMainThread 把代码添加到队列, 例如:
|
1
2
3
4
5
6
7
|
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 来防止内存泄漏, 如果要这样做的话, 用下面的代码包含你的代码即可:
|
1
2
3
4
5
|
void
MyThreadStart(
object
arg) {
using
(
var
ns =
new
NSAutoReleasePool()) {
// Your code goes here.
}
}
|
张志敏所有文章遵循创作共用版权协议,要求署名、非商业 、保持一致。在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处。
本博客已经迁移到 GitHub , 围观地址: http://beginor.github.io/