2017-10-13 104 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

相關問題