如何清理 MonoTouch 中的线程?
查看 Instruments 中的 Time Profiler 工具,看起来我在使用线程后没有处理它们。当我执行启动线程的操作时,“所有线程”列表会不断增长。
我按如下方式启动线程(“线程”是函数的本地函数):
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
Thread thread = new Thread(Dispatch);
thread.Start();
Dispatch() 函数是:
private void Dispatch()
{
using (NSAutoreleasePool autoreleasePool = new NSAutoreleasePool())
{
try
{
// Calls a web service.
_workDispatcher.Dispatch();
}
finally
{
// Resets network activity indicator after thread complete.
InvokeOnMainThread(() => { UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false; });
}
}
}
_workerDispatcher.Dispatch 调用 Web 服务。
我还应该做什么来在完成后销毁线程?
应用程序在很长一段时间后崩溃 - 我们猜测它可能是线程 - 因为它定期启动它们来执行较短的操作。我读过,由于垃圾收集,监视 MonoTouch 中的内存使用情况是一个挑战 - 或者我会查看内存是否也被消耗(例如,被剩余的线程消耗)。
我正在使用 MonoTouch 3.2.5 和 iOS 4.3.1(以及 Xcode 4 中的 Instruments)。应用程序需要在 iOS 3.x 上运行,因此我无法使用 Grand Central Dispatch。
Looking at the Time Profiler instrument in Instruments, it looks like I'm not disposing of threads after I've used them. The list of "All threads" grows as I do operations that start a thread.
I start my thread as follows ("thread" is local to the function):
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
Thread thread = new Thread(Dispatch);
thread.Start();
The Dispatch() function is:
private void Dispatch()
{
using (NSAutoreleasePool autoreleasePool = new NSAutoreleasePool())
{
try
{
// Calls a web service.
_workDispatcher.Dispatch();
}
finally
{
// Resets network activity indicator after thread complete.
InvokeOnMainThread(() => { UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false; });
}
}
}
_workerDispatcher.Dispatch makes a call to a web service.
What more should I be doing to destroy the thread on completion?
The application crashes after an extended period of time - and we're guessing it might be threads - as it launches them regularly to conduct shortish operations. I've read that monitoring memory usage in MonoTouch is a challenge due to garbage collection - or I'd see if memory was also being consumed (e.g. by threads remaining).
I'm using MonoTouch 3.2.5 and iOS 4.3.1 (and Instruments in Xcode 4). App needs to work on iOS 3.x, so I can't use Grand Central Dispatch.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您确定这些是您的线程吗?更有可能的是,MonoTouch 保留了一些线程池线程以供将来的异步操作(例如调用 Web 服务中的操作)。
Are you certain these are your threads? Its far more likely that MonoTouch is keeping some threadpool threads around for future async operations (like the one in the call to your web service).
MonoTouch 使用两种线程:一种是使用 Thread.Start 手动启动的线程,另一种是根据异步方法调用按需创建的线程(内部许多同步操作只是异步操作的包装器)或使用 ThreadPool 时创建的线程.QueueUserWorkItem 或当您使用并行框架的默认任务计划程序时。
您可能会看到 ThreadPool 线程被自动配置为每个 CPU N 个(我不记得实际数量,但您可以通过 ThreadPool 中的属性找到)。
当您在具有单核的设备上运行时,因此线程上限为 N。当您在 iPad 2 上运行时,线程上限为 2*N,当您在具有 8 核的精美 iMac 上运行时,该数字为8*N。这只是 Mono 调整自己以适应更多 CPU 的方式。
MonoTouch uses two kinds of threads: the ones that you manually launch with Thread.Start and the ones that are created on demand in response to asynchronous methods invocations (internally many synchronous operations are merely wrappers around the asynchronous ones) or created when you use ThreadPool.QueueUserWorkItem or when you use the Parallel Framework's default Task scheduler.
What you might be seeing are the ThreadPool threads which are automatically configured to be N per CPU (I do not remember the actual number, but you can find out through a property in the ThreadPool).
When you run on the device you have a single core, so the threads are capped at N. When you run on an iPad 2 the threads are capped at 2*N, when you are running on a fancy iMac with 8 cores that number is 8*N. This is just Mono's way of adjusting itself to more CPUs.
看起来这是一个垃圾收集问题。如果我在线程完成后调用 GC.Collect(),线程数量似乎不会继续增长。
It looks like this was a garbage collection issue. If I put a call to GC.Collect() after the thread completes, the number of threads doesn't appear to keep growing.