C# InvokeOnAppThread在应用程序线程上调用时抛出错误

C# InvokeOnAppThread在应用程序线程上调用时抛出错误,c#,multithreading,unity3d,C#,Multithreading,Unity3d,在Unity中,我在一个脚本中添加了以下代码,该脚本连接到一个通用游戏对象,该对象中包含一个立方体: using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Threading; //using System.Runtime.Tasks; public class ExampleScript : MonoBehaviour { // Use this for

在Unity中,我在一个脚本中添加了以下代码,该脚本连接到一个通用游戏对象,该对象中包含一个立方体:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
//using System.Runtime.Tasks;

public class ExampleScript : MonoBehaviour {

    // Use this for initialization
    void Start () 
    {
        Debug.Log ("Start():: Starting");
        //SlowJob ();

        Thread myThread = new Thread (SlowJob);

        myThread.Start ();

        Debug.Log ("Start():: Done");

    }

    // Update is called once per frame
    void Update () {

        //Option 1) This will move the cube in the application thread
        //this.transform.Translate (Vector3.up * Time.deltaTime);

    }


    void SlowJob()
    {

        Debug.Log ("ExampleScript::SlowJob() --Doing 1000 things, each taking 2ms ");

        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start ();

        for (int i = 0; i < 1000; i++) 
        {
            //Option 2) We are trying to move the cube in the secondary thread! ooops!!
            //this.transform.Translate (Vector3.up * 0.002f);
            //get_transform can only be called from the main thread

            //Option 3) We are going to try to use a delegate on application thread 
            UnityEngine.WSA.Application.InvokeOnAppThread (()=>{
                this.transform.Translate (Vector3.up * 0.002f);
            },false);

            //Option4
/*          UnityEngine.WSA.Application.InvokeOnUIThread (()=>{
                this.transform.Translate (Vector3.up * 0.002f);
            },false);
*/
            Thread.Sleep (2);  //sleep for 2ms

        }

        sw.Stop ();

        Debug.Log ("ExampleScript::SlowJob() --Done!  Elapsed Time:" + sw.ElapsedMilliseconds / 1000f);


    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用系统线程;
//使用System.Runtime.Tasks;
公共类示例脚本:MonoBehavior{
//用于初始化
无效开始()
{
Log(“Start()::Starting”);
//SlowJob();
Thread myThread=新线程(SlowJob);
myThread.Start();
Log(“Start()::Done”);
}
//每帧调用一次更新
无效更新(){
//选项1)这将在应用程序线程中移动多维数据集
//this.transform.Translate(Vector3.up*Time.deltaTime);
}
void SlowJob()
{
Log(“ExampleScript::SlowJob()--做1000件事,每件事花费2ms”);
System.Diagnostics.Stopwatch sw=新的System.Diagnostics.Stopwatch();
sw.Start();
对于(int i=0;i<1000;i++)
{
//选项2)我们正在尝试在次线程中移动多维数据集!ooops!!
//this.transform.Translate(Vector3.up*0.002f);
//get_transform只能从主线程调用
//选项3)我们将尝试在应用程序线程上使用委托
UnityEngine.WSA.Application.InvokeOnAppThread(()=>{
this.transform.Translate(Vector3.up*0.002f);
},假);
//选择4
/*UnityEngine.WSA.Application.InvokeOnUIThread(()=>{
this.transform.Translate(Vector3.up*0.002f);
},假);
*/
Thread.Sleep(2);//睡眠2ms
}
sw.Stop();
Log(“ExampleScript::SlowJob()--Done!运行时间:”+sw.elapsedmillyses/1000f);
}
}
正如您所看到的,有一个SlowJob函数正在另一个线程上执行。 现在,我想更新unity中的一些内容(本例中的立方体) 所以我尝试了四件事:

  • 在主线程中移动多维数据集。这很好,应该是这样的
  • 从次线程中移动多维数据集。这当然行不通。错误显示“get_transform只能从主线程调用。这当然是意料之中的
  • 使用InvokeOnAppThread移动多维数据集。(稀少的)文档说这会调用应用程序线程上的委托。我认为这应该可以工作。但它会抛出相同的错误
  • 为了尝试,我还尝试了invokeonuthread,但出现了相同的错误
  • 我的问题是为什么选项3不起作用?我以为InvokeOnAppThread用于这些情况

    (以防万一,关于InvokeOnAppThread,我只问了另外一个问题。这是一个不同的问题,所以这不是重复的问题)

    我的问题不是如何从另一个线程调用unity东西(尽管它也解决了这个问题)。我的问题是为什么InvokeOnAppThread不适用于此?

    我知道有很多复杂的方法可以解决这个问题。这不是这个问题的核心

    我重申这不是一个重复的问题

    非常感谢任何有用的建议

    我的问题是为什么选项3不起作用?我想 在这些案件中使用了

    InvokeOnAppThread
    函数不用于从另一个线程调用Unity的主线程。它用于Unity和Windows App线程之间的通信。此函数用于将Windows App与XAML结合为本机方式时,然后决定将Unity集成到此项目中。您可以将其用作向我发送消息的桥梁从应用程序主线程上的本机端到Unity的消息,反之亦然。它并不意味着要从您创建的另一个
    线程调用,就像您所想的和您当前正在使用的那样

    InvokeOnAppThread
    InvokeOnUIThread
    函数的文档记录得很差,但为了简化它们:

    InvokeOnAppThread
    -用于将方法从XAML调用到Unity

    InvokeOnUIThread
    -用于将方法从Unity调用为XAML

    这是过去的情况,希望它仍然存在。有关示例,请参见和

    此外,它来自WSA
    命名空间,一旦您使用它,您就无法为Windows平台以外的任何其他平台构建应用程序。您的项目将无法为Android、iOS、Mac和其他平台构建

    最后,您没有与之通信的Windows XAML应用程序,因此不需要
    InvokeOnAppThread
    。同样,
    InvokeOnAppThread
    也不用于线程与Unity的主线程之间的通信。它用于在用XAML和Unity制作的程序的Windows端之间进行通信。您只需要使用Unity API即可在另一个
    线程中
    。您必须创建自己的函数/包装器来实现这一点,或者使用我已经使用的函数/包装器

    我的问题是为什么选项3不起作用?我想 在这些案件中使用了

    InvokeOnAppThread
    函数不用于从另一个线程调用Unity的主线程。它用于Unity和Windows App线程之间的通信。此函数用于将Windows App与XAML结合为本机方式时,然后决定将Unity集成到此项目中。您可以将其用作向我发送消息的桥梁从应用程序主线程上的本机端到Unity的消息,反之亦然。它并不意味着要从您创建的另一个
    线程调用,就像您所想的和您当前正在使用的那样

    InvokeOnAppThread
    InvokeOnUIThread
    函数的文档记录得很差,但为了简化它们:

    InvokeOnAppThread
    -用于将方法从XAML调用到Unity

    InvokeOnUIThread
    -用于将方法从Unity调用为XAML

    这是wh