【问题标题】:Google Daydream Thread with Unity带有 Unity 的 Google Daydream 线程
【发布时间】:2017-06-30 00:06:25
【问题描述】:

我正在尝试在我的 Unity 项目中使用线程,该项目正在部署在 Android 手机上以与 Google Daydream VR 系统一起使用。我遇到了一个问题,即线程没有像我预期的那样死亡。

我正在创建一个如下所示的线程,并为其分配一个函数以在“活着”时运行。当发生特定操作时(在我的情况下,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() 中的任务中途停止并且不再进入。 Update() 函数继续循环,但 thread.IsAlive 继续声明线程处于活动状态,当我理解它已停止操作时。如果我退出该脚本正在其中运行的场景,则线程会终止并且脚本会按预期继续,但是当我留在场景中时它不会终止。我不知道为什么。

几乎与此相同的代码已在 Windows 机器上进行了测试,在 Unity 中运行,它的工作方式完全符合我的预期,这让我相信这可能是一个 Android/Daydream 问题。

在诊断发生的事情方面的任何帮助都会很棒。由于重现问题所需的代码、场景和平台的规模,很难发布 MWE(抱歉)。

更新:更改了我的 Windows 代码以更接近地复制 Android 版本。现在可以确认这是 Android/Daydream 问题,而不是“场景切换”问题。 Windows 版本按预期正确终止了线程。

【问题讨论】:

    标签: c# android multithreading unity3d daydream


    【解决方案1】:

    我建议将 void Update 设为 Public,但由于我们看不到代码,因此很难看到您在此处尝试执行的操作。您也可以使用 isAlive 进行 while 循环!= true。但根据您的程序,这可能不是一个好主意。

    【讨论】:

    • 谢谢。我将更新更改为公开,但对问题没有帮助。我的代码已经在 Update 函数中寻找 isAlive != true 的时间,该函数在 Windows 上运行良好,但在 Android/Daydream 上无法正常运行。
    【解决方案2】:

    首先:使用IsBackground 告诉.Net 在应用程序退出时关闭线程。

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

    当线程在您的示例中退出 Run 时,它将死亡。我不确定你为什么没有看到这个,但如果有任何阻塞,我建议查看 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 函数就会停止,而 Update 继续运行。直到我离开现场,才抛出 ThreadAbortException。这个问题似乎与 Unity 场景有关,因为我的 Windows 版本在 Unity 中运行时没有这个问题。
    • 作为更新,这与 Unity 场景无关,因为我已经调整了我的 Windows 代码以更接近地复制 Android 版本,我确信这是一个 Android/Daydream 移植问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多