使用 Unity 的 Google Daydream 线程 [英] Google Daydream Thread with Unity

查看:41
本文介绍了使用 Unity 的 Google Daydream 线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to use threads in my Unity project which is being deployed on an Android phone for use with the Google Daydream VR system. I'm having an issue where the thread isn't dying as I would expect it to.

我正在创建一个如下所示的线程,并为其分配一个在活着"时运行的函数.当发生特定操作时(在我的情况下,UDP 网络出现故障),线程应该停止执行并终止.然而,该线程停止执行其功能,但并没有消亡.

I'm creating a thread like that seen below, and assigning it a function to run while 'alive'. When a specific action occurs (in my case, a UDP network goes down), the thread should stop performing and die. However, the thread stops performing its function but isn't dying.

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 继续声明该线程处于活动状态,据我所知,它已停止运行.如果我退出该脚本在其中运行的场景,则线程会终止并且脚本会按预期继续运行,但是当我留在场景中时它不会终止.我不知道为什么.

In the example above, the thread is created, and runs its task within Run(). When the action occurs, is stops midway through its task within Run() and doesn't enter again. The Update() function continues to loop, but thread.IsAlive continues to state that the thread is alive, when it's my understanding it has ceased operation. If I exit the scene that this script is running within, the thread dies and the script continues as expected, but it won't die while I stay within the scene. I have no idea why.

与此几乎相同的代码已经在 Windows 机器上进行了测试,在 Unity 中运行,并且完全符合我的预期,这让我相信这可能是 Android/Daydream 问题.

Almost identical code to this has been tested on a Windows machine, running within Unity, and it works exactly as I expect, which is making me believe this could be an Android/Daydream issue.

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

Any help in diagnosing what's going on would be great. It's hard to post a MWE due to the scale of the code, scenes, and platform required to recreate the issue (sorry).

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

推荐答案

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

First off: Use IsBackground to tell .Net to shut down the thread when application exits.

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

当线程退出您的示例中的 Run 时,它将死亡.我不知道为什么你没有看到这个,但如果有任何阻塞,我建议查看 Run 中的代码.这样做的一个好方法是附加 Visual Studio 调试器,冻结程序并转到 Debug->Windows->Parallel Stacks.它将为您提供线程及其堆栈的可视化表示.

When the thread exits Run in your example it will die. I'm not sure why you are not seeing this, but I suggest looking at the code inside Run if anything is blocking. A good way to do this is to attach Visual Studio debugger, freeze program and go to Debug->Windows->Parallel Stacks. It will give you a visual representation of threads and their stacks.

启动一个线程有很多开销.空闲线程几乎没有开销.从它的外观来看,您可以从不同的方法中受益.您基本上是在每次完成时尝试重新启动线程.

Starting a thread has a lot of overhead. Idling a thread has near no overhead. From the look of it you could benefit from a different approach. You are basically trying to restart the thread every time it finishes.

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
        }
    }
}

或者,您可以让 Run-thread 一直等待,直到 Update 向它传递一个信号.

Alternatively you can keep the Run-thread waiting until Update passes it a signal.

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();
    }
}

这篇关于使用 Unity 的 Google Daydream 线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆