2012-10-23 123 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

我認爲這是絕對的最後手段,但是,因爲任務涉及在未知速度和可靠性的網絡上下載未知大小的文件,所以還不清楚在放棄和假定後臺線程是多少時間之前太多時間死。 –

相關問題