2012-10-23 171 views
6

我有一个后台线程正在做一堆工作 - 加载应用程序。主线程在UIProgressView上显示进度。一个线程如何确定另一个线程是否已经崩溃?

后台线程正在与performSelectorInBackground催生了(虽然我不结婚这种方法,如果采用不同的方法,使这个问题更容易解决)

[self performSelectorInBackground:@selector(loadAppInBackground) withObject:self]; 

一对夫妇的场合中的错误造成的后台线程崩溃(随着应用程序的发展而出现不同的错误),导致进度条停止,但用户没有明确指出任何错误。

我想要检测到这种情况,并且比简单地挂起直到用户放弃等待时更失败。

由于加载过程的持续时间可能会有很大差异,因此简单超时并不是理想的选择。

前台线程检测后台线程失败的最佳方式是什么?由于前台线程忙于处理UI,是否需要第二个后台线程来监视第一个?这看起来很难看。

是否有一些可用于“ping”后台进程的线程间通信机制?更好的是,检查其他线程状态的低级系统机制?

调试器知道所有正在运行的线程......并且似乎知道它们的状态。我想知道是否有一个电话可用于我的应用程序来做同样的事情。

+1

你如何派遣这个背景工作(GCD,NSOperations,NSThreads)?答案取决于你的实施。 – CodaFi

+0

[self performSelectorInBackground:@selector(loadAppInBackground)withObject:self]; –

+0

超时是最常用的技术。因为无法确定线程是否正常运行或无限循环(暂停问题)。因此,您的前台可以检查后台任务是否在1秒内完成(本地I/O,或网络I/O的15〜60秒)。对不起,我只能提出一个模糊的建议,因为你在问一个普遍的问题。 – HKTonyLee

回答

0

似乎目标c中没有机制直接检查后台线程的状态。任何提供的答案都是体面的选择......要么超时,要么让线索创造出持续存在的某种证据。

我希望能更简单,更可靠,更实时。

我将尝试在线程中捕获异常,并可能生成诸如“BackgroundThreadException”的通知,前台线程可以侦听并作出反应。

1

如果后台任务以某种常规周期运行(例如,有大量工作完成的大循环),它可以每隔一段时间设置一个标志以指示它仍然存在。

这样做的一种方法是让后台线程存储[NSDate timeIntervalSinceReferenceDate]某处,并且在您的主线程中偶尔(可能在一个计时器上)将它与当前时间进行比较。如果差异大于某个合理的限制,则可以猜测后台线程已经死亡。

另一种方法是让后台线程简单地设置一个布尔值,并让主线程定期询问并清除它。如果在主线程询问之间没有再次设置布尔值,则可以推断它已经死亡。

第一种技术的优点是,您可以“调整”“合理限制”以容忍代码(在任一线程中),它的定时有点不规范。第二种方法通常要求时间更具可预测性。

当然,如果后台线程刚刚完成并且您还没有识别出来,那么您希望以某种方式避免“吹口哨”。

+0

是的,B计划是使用超时,我们不需要超时整个过程。整个加载过程中的每个步骤都可以单独超时。我只是希望有人打电话说,从前台我可以自信地验证一个不同的线程仍在运行 - 而不是通过检查一些副作用来验证它是否在任意时间运行。 –

+0

@DaveOwens - 问题在于,“线程死亡”常常永远挂在一个锁上,或者陷入某种循环,而只是停止执行。 –

1

一个常见的技术是有一个额外的线程来检查有问题的线程的生命体征 - 所谓的心跳线程。心跳线程通过检查线程是否及时响应来轮询线程,如果不是,则认为线程已经死亡并终止线程。

一个简单的心跳线程实现将检查一个计数器,该计数器由另一个线程定期增加,如果该计数器在一定时间内没有增加,则认为该死亡计数器被视为死亡,然后可以采取适当的措施,如重新启动线程或杀死应用程序。另一种更常见的方法是,如果hb线程将消息发送到线程并检查超时响应。

+0

我认为这是绝对的最后手段,但是,因为任务涉及在未知速度和可靠性的网络上下载未知大小的文件,所以还不清楚在放弃和假定后台线程是多少时间之前太多时间死。 –

相关问题