2017-06-30 38 views
0

我試圖在其中部署在Android手機上與谷歌的白日夢VR系統中使用我的統一項目中使用線程。我有一個問題,線程沒有像我期望的那樣死去。谷歌白日夢主題使用Unity

我創建了一個如下所示的線程,併爲其分配了一個函數,以便在「活着」時運行。當一個特定的動作發生時(在我的情況下,一個UDP網絡關閉),線程應該停止執行並且死掉。但是,該線程停止執行其功能,但不會死亡。

Thread thread; 

private void Update() 
{ 
    if (!thread.IsAlive) 
    { 
     // Create a new thread. 
    } 
} 

public void createNewThread() 
{ 
    thread = new Thread(Run); 
    thread.Priority = System.Threading.ThreadPriority.BelowNormal; 
    thread.Start(); 
} 

void Run() 
{ 
    // Do thread task. 
} 

在上面的例子中,創建了線程,並在Run()中運行它的任務。當動作發生時,在Run()內的任務中途停止,並且不會再次進入。更新()函數繼續循環,但thread.IsAlive繼續指出線程是活的,當它是我的理解它已停止運作。如果我退出腳本運行的場景,線程就會死亡,並且腳本按預期繼續運行,但當我停留在場景中時,腳本不會死亡。我不知道爲什麼。

幾乎完全相同的代碼已經在Unity機器上運行的Windows機器上測試過,它的工作原理與我的預期完全相同,這讓我相信這可能是Android/Daydream問題。

診斷髮生了什麼事情將是巨大的任何幫助。由於重新創建問題所需的代碼,場景和平臺的規模(很抱歉),很難發佈MWE。

更新:更改我的Windows代碼以更接近地複製Android版本。現在可以確認這是Android/Daydream問題,而不是「場景切換」問題。 Windows版本按預期正確地殺死了線程。

回答

0

我會建議做無效的更新公開,但很難看到你在這裏做什麼,因爲我們沒有看到代碼。您也可以在while循環中執行isAlive!= true。但取決於你的計劃,這可能不是一個好主意。

+0

謝謝。我將更新更改爲公開,但它沒有幫助解決問題。我的代碼已經在尋找什麼時候isAlive!= true的Update函數,它在Windows上工作正常,但在Android/Daydream上無法正確執行。 – ritchie888

0

首先:使用IsBackground告訴.Net在應用程序退出時關閉線程。

thread = new Thread(Run); 
thread.Priority = System.Threading.ThreadPriority.BelowNormal;` 
thread.IsBackground = true; 
thread.Start(); 

當你的榜樣運行的線程退出它會死。我不知道爲什麼你沒有看到這個,但我建議看看Run中的代碼是否有阻塞。執行此操作的一個好方法是連接Visual Studio調試器,凍結程序並轉到Debug-> Windows-> Parallel Stacks。它會給你一個線程及其棧的直觀表示。

啓動一個線程有很大的開銷。怠速線程幾乎沒有開銷。從它的外觀你可以從不同的方法中受益。每次完成時基本上都要重新啓動線程。

using UnityEngine; 
using System.Threading; 

public class Test : MonoBehaviour 
{ 
    private Thread _thread; 
    void Start() 
    { 
     _thread = new Thread(Run); 
     _thread.Name = "DaydreamThread"; 
     _thread.Priority = System.Threading.ThreadPriority.BelowNormal; 
     _thread.IsBackground = true; 
     _thread.Start(); 
    } 

    private void Run() 
    { 
     try 
     { 
      // Endless loop 
      for (;;) 
      { 
       // Do your stuff 
      } 
     } 
     catch (ThreadAbortException) 
     { 
      // If you expect to do a Abort() on the thread then you want to 
      // ignore this exception 
     } 
    } 
} 

或者,您可以保持運行線程等待,直到Update傳遞給它一個信號。

using UnityEngine; 
using System.Threading; 

public class Test : MonoBehaviour 
{ 
    private Thread _thread; 
    private ManualResetEvent _signal = new ManualResetEvent(false); 
    void Start() 
    { 
     _thread = new Thread(Run); 
     _thread.Name = "DaydreamThread"; 
     _thread.Priority = System.Threading.ThreadPriority.BelowNormal; 
     _thread.IsBackground = true; 
     _thread.Start(); 
    } 

    private void Run() 
    { 
     try 
     { 
      // Endless loop 
      for (;;) 
      { 
       // Wait for a signal to do another pass 
       _signal.WaitOne(); 
       _signal.Reset(); 


       // Do your stuff 
      } 
     } 
     catch (ThreadAbortException) 
     { 
      // If you expect to do a Abort() on the thread then you want to 
      // ignore this exception 
     } 
    } 

    void Update() 
    { 
     if (something) 
      // Signal Run-thread to do another pass 
      _signal.Set(); 
    } 
} 
+0

我會檢查它是否僅僅是「的IsAlive」編譯爲Android原生是馬車。如果沒有,你可以解決它,例如上面的建議。 –

+0

感謝您的輸入,但執行的IsBackground錯誤地同我目前的執行情況。一旦該操作導致線程死機,則Run繼續運行時停止Run函數。直到我離開現場時才拋出ThreadAbortException。這個問題似乎與Unity場景有關,因爲我的Unity版本的Windows版本沒有這個問題,只有一個場景。 – ritchie888

+1

作爲一個更新,這不是Unity場景相關的,因爲我已經調整了我的Windows代碼以更接近地複製Android版本,我相信這是Android/Daydream移植問題。 – ritchie888