2017-10-13 101 views
0

在Unity我已经连接到一个通用的游戏对象的脚本中有一个多维数据集下面的代码:InvokeOnAppThread调用的应用程序线程抛出一个错误

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


    } 
} 

正如你可以看到有一个SlowJob功能即在另一个线程上执行。 现在,我想更新团结的东西(在这种情况下,立方体) 于是,我四件事情:

  1. 移动在主线程的立方体。这很好,因为它应该
  2. 从辅助线程移动多维数据集。这当然不起作用。错误提示“get_transform只能从主线程调用,这当然是可以的
  3. 使用InvokeOnAppThread移动多维数据集(稀少)文档说这调用了应用程序线程上的一个委托我认为这个应该的工作,但它会引发同样的错误
  4. 只是为了试试我也试过InvokeOnUIThread具有相同的错误。

我的问题是,为什么选择3不起作用?我以为InvokeOnAppThread用于这些案件

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

我的问题不是如何从另一个线程调用统一的东西(虽然它解决了为好)。我的问题是为什么InvokeOnAppThread不适用于此?

我知道有很复杂的方法来解决这个问题。这不是什么这个问题是关于

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

任何有用的建议非常赞赏

+0

这两个函数仅适用于Windows。查看如何从另一个'Thread'调用Unity API的副本。 – Programmer

+0

'this.transform'只能由创建它的线程访问。我不知道'InvokeOnAppThread'是干什么的,但即使调用的线程没有创建'this.transform'对象,也使用它,那么它就无法访问它。 – CodingYoshi

+0

@CodingYoshi不幸的是InvokeOnAppThread是一个记录不完善的函数。你说的是真的(因此选项2不起作用),但我认为这个选项是为了完成那个 – KansaiRobot

回答

2

我的问题是,为什么选择3不起作用?我以为InvokeOnAppThread 用于这些情况

InvokeOnAppThread功能不是用来做团结的从另一个线程主线程调用。它用于Unity和Windows App Thread之间的通信。使用XAML以本地方式制作Windows应用程序时使用此功能,然后再决定将Unity集成到此项目中。您可以将它用作桥接器,从App主线程上的本机端发送消息到Unity,反之亦然。这并不意味着从您创建的另一个Thread中调用,就像您以为和您目前正在使用它一样。

InvokeOnAppThreadInvokeOnUIThread功能记录不完整,但简化它们:

InvokeOnAppThread - 用于从XAML调用方法统一。

InvokeOnUIThread - 用于从Unity调用方法到XAML。

这就是过去的习惯,希望它仍然有办法。示例见Ref1Ref2

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

最后,您没有与您通信的Windows XAML应用程序,因此您不需要InvokeOnAppThread。再次,InvokeOnAppThread不用于在您的线程和Unity的主线程之间进行通信。它用于在使用XAML和Unity编程的Windows程序之间进行通信。你只是想在另一个Thread中使用Unity API。你要么做出自己的功能/包装,要么使用我已经从here制作的那个。

+0

我的想法来自这个http://www.roadtoholo.com/2016/05/04/1601/text-to-speech-for-hololens/ – KansaiRobot

相关问题