2012-10-23 8 views
6

私は仕事の束をしているバックグラウンドスレッドを持っています - アプリケーションをロードしています。メインスレッドは、UIProgressViewで進行状況を表示しています。あるスレッドは、別のスレッドがクラッシュしたかどうかを判断できますか?

カップルの機会に

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

は、バグが発生しました(別のアプローチは、この問題は簡単に解決できる場合しかし、私はこの方法には結婚ではないよ)バックグラウンドスレッドはperformSelectorInBackgroundで生み出されていますバックグラウンドスレッドがクラッシュする(アプリケーションが進化するにつれて異なるバグ)ので、プログレスバーは停止しますが、何も間違っていることを明確に知らされません。

私はこの状況を検出したいと思っています。ユーザーが待っていなくても、単にハングするよりも、うまく機能しません。

ロードプロセスの時間が大幅に異なる可能性があるため、タイムアウトは理想的な選択肢ではありません。

フォアグラウンドスレッドがバックグラウンドスレッドが失敗したことを検出する最も良い方法は何ですか?フォアグラウンドスレッドはUIを処理するために忙しいので、最初のバックグラウンドスレッドを監視する必要がありますか?それは醜いようです。

バックグラウンドプロセスに「ping」するために使用できるスレッド間通信メカニズムがありますか?他のスレッドの状態をチェックする低レベルのシステムメカニズムはありますか?

デバッガは、実行中のすべてのスレッドについて認識しており、ステータスを把握しているようです。私は同じことをするために私のアプリに利用可能なコールがあるのだろうかと思っています。

+1

この背景作業(GCD、NSOperations、NSThreads)はどのように派遣していますか?答えは実装によって異なります。 – CodaFi

+0

[self performSelectorInBackground:@セレクタ(loadAppInBackground)withObject:self]; –

+0

タイムアウトは主に使用されるテクニックです。スレッドが正常に動作しているのか、無限ループ中であるのか(異常終了しているのか)を判断することができないためです。したがって、バックグラウンドタスクが1秒(ローカルI/O、またはネットワークI/Oの場合は15〜60秒)で完了したかどうかを確認できます。申し訳ありませんが、一般的な問題を尋ねているのであいまいな提案しかできません。 – HKTonyLee

答えて

0

バックグラウンドスレッドの状態を直接チェックする目的は、目的cにはメカニズムがないようです。提供された回答のいずれかが適切なオプションです...タイムアウトするか、スレッドが継続的存在の何らかの種類の証拠を作成しています。

私は少しシンプルで信頼性の高いリアルタイムを望んでいました。

スレッドで例外をキャッチし、フォアグラウンドスレッドがリッスンして反応できる「BackgroundThreadException」のような通知を生成することを実験します。

1

バックグラウンドタスクが何らかの定期的なサイクルで実行されている場合(例えば、多くの作業が行われる大きなループがある場合など)、フラグが頻繁に設定され、まだ生きていることを示します。

これを行う1つの方法は、バックグラウンドスレッドストア[NSDate timeIntervalSinceReferenceDate]をどこかに置いて、あなたのメインスレッドで時々(おそらくタイマーで)現在の時刻と比較することです。差がある合理的な限界よりも大きい場合は、バックグラウンドスレッドが死んだと推測できます。

もう1つの方法は、バックグラウンドスレッドにブール値を設定し、メインスレッドにそれを問い合わせて定期的にクリアさせる方法です。ブール値がメインスレッドの質問の間に再び設定されない場合、あなたはそれが死んだと推論することができます。

最初の手法には、タイミングがやや不規則なコード(どちらのスレッドでも)を許容するために「合理的な制限」を「調整」できるという利点があります。第2のアプローチは、一般に、より予測可能なタイミングを必要とする。

どちらのアプローチでも、バックグラウンドスレッドがちょうど終了し、単にそれをまだ認識していない場合、何とか "笛を吹く"のを避けたいと思うのはもちろんです。

+0

はい、プランBはタイムアウトを使用するため、プロセス全体をタイムアウトする必要はありません。ロードプロセス全体の個々のステップは、個別にタイムアウトすることができます。フォアグラウンドから、別のスレッドがまだ実行中であることを自信を持って確認することができました。何らかの副作用をチェックすることによって、何らかの前に実行されていることを確認するのではなく、 –

+0

@DaveOwens - 問題は、「スレッドの死」は、しばしば、ロックに永久にぶら下がっているか、何らかのループに巻き込まれすぎていることです。 –

1

一般的な手法は、問題のスレッドの生命徴候をチェックするために余分なスレッドを用意することです。いわゆるハートビートスレッドです。ハートビートスレッドは、適時に応答するかどうかをチェックしてスレッドをポーリングし、そうでない場合は、スレッドがデッドしたとみなして終了します。

シンプルハートビートスレッドを実装すると、他のスレッドによって定期的にインクリメントされるカウンタをチェックすることができます。カウンタが一定時間内にインクリメントされず、デッドと見なされ、スレッドの再起動またはアプリを殺す。もう1つのより一般的な方法は、hbスレッドがスレッドにメッセージを送信し、タイムアウトのある応答をチェックする場合です。

+0

私は絶対的な最後の手段として動作すると思いますが、未知の速度と信頼性のネットワーク上で未知のサイズのファイルをダウンロードする作業が含まれているため、あきらめてバックグラウンドスレッドを仮定すると、デッド。 –

関連する問題