谷歌白日梦主题使用Unity

问题描述:

我试图在其中部署在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版本按预期正确地杀死了线程。

我会建议做无效的更新公开,但很难看到你在这里做什么,因为我们没有看到代码。您也可以在while循环中执行isAlive!= true。但取决于你的计划,这可能不是一个好主意。

+0

谢谢。我将更新更改为公开,但它没有帮助解决问题。我的代码已经在寻找什么时候isAlive!= true的Update函数,它在Windows上工作正常,但在Android/Daydream上无法正确执行。 – ritchie888

首先:使用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