谷歌白日梦主题使用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。但取决于你的计划,这可能不是一个好主意。
首先:使用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();
}
}
我会检查它是否仅仅是“的IsAlive”编译为Android原生是马车。如果没有,你可以解决它,例如上面的建议。 –
感谢您的输入,但执行的IsBackground错误地同我目前的执行情况。一旦该操作导致线程死机,则Run继续运行时停止Run函数。直到我离开现场时才抛出ThreadAbortException。这个问题似乎与Unity场景有关,因为我的Unity版本的Windows版本没有这个问题,只有一个场景。 – ritchie888
作为一个更新,这不是Unity场景相关的,因为我已经调整了我的Windows代码以更接近地复制Android版本,我相信这是Android/Daydream移植问题。 – ritchie888
谢谢。我将更新更改为公开,但它没有帮助解决问题。我的代码已经在寻找什么时候isAlive!= true的Update函数,它在Windows上工作正常,但在Android/Daydream上无法正确执行。 – ritchie888