2016-01-10 164 views
1

完成至於我的學校項目的一部分,我試圖鏈接兩個表,以減少存儲在一個表中的數據量,所以我想和鏈接我的「成績」級我的「CorrectAnswers」類通過ObjectID。然而,由於任務是異步的,當一個任務完成保存時,另一個任務已經開始或者也完成保存,因此ObjectID返回爲空。等待一個parse.com異步任務Unity3D

下面是我使用的代碼:

public void SaveScore() 
{ 

    ParseObject SendScore = new ParseObject("Scores"); 
    SendScore["Score"] = CheckAnswer.score; 
    SendScore["user"] = ParseObject.CreateWithoutData("_User", ParseUser.CurrentUser.ObjectId); 
    SendScore["TestMode"] = MainMenu.testmode; 
    SendScore["TotalQuestions"] = QuestionCreation.TotalQuestions; 
    SendScore["CorrectQuestions"] = CheckAnswer.CorrectQuestions; 


    SendScore.SaveAsync().ContinueWith(t => 
    { 
     ScoreObjectId = SendScore.ObjectId; 
    }); 

    ParseObject SendCorrectTopics = new ParseObject("CorrectAnswers"); 
    SendCorrectTopics["Score"] = SendScore.ObjectId; 
    for (int i = 0; i <= 9; i++) 
    { 
     string Topic = "Topic" + (i + 1).ToString(); 
     SendCorrectTopics[Topic] = CheckAnswer.CorrectTopics[i]; 
    } 

    SendCorrectTopics.SaveAsync(); 

    SceneManager.LoadScene(0); 
} 

我將如何能夠使第二保存持有,直到第一次保存已完成?我對C#有點新,所以不太清楚它的所有功能。我研究過「等待」,但團結似乎不喜歡那樣。任何幫助將不勝感激! 由於提前,

+0

有人認爲......作爲「Fon Masta」,你將不得不進入Parse的服務器代碼。試一試,它很容易開始。 – Fattie

回答

1

編輯:好的,在統一的協同程序多一點讀書後,我發現檢查,只有依賴於必要時檢查的一個更好的方法:

IEnumerator CheckSave() 
{ 
    while(ScoreObjectId == null & !DoneSave)) 
    { 
     print("Running"); 
     yield return new WaitForSeconds(0.5f); 
    } 
    DoneSave = false; 
    SaveTotalTopics(); 

} 

這似乎是一個很大更好的做法。

好吧,看來答案是我已經做過,哪怕是一點點醜。

使用Unity的更新功能,我創建了一個檢查,以確保該對象ID不爲空和以前保存已經完成,像這樣:

void Update() { 
    if (ScoreObjectId != null & DoneSave) 
    { 
     DoneSave = false; 
     SaveTotalTopics(); 
    } 

因此,它分成兩個保存和創造:

public void SaveScore() 
{ 
    ParseObject SendScore = new ParseObject("Scores"); 
    SendScore["Score"] = CheckAnswer.score; 
    SendScore["user"] = ParseObject.CreateWithoutData("_User", ParseUser.CurrentUser.ObjectId); 
    SendScore["TestMode"] = MainMenu.testmode; 
    SendScore["TotalQuestions"] = QuestionCreation.TotalQuestions; 
    SendScore["CorrectQuestions"] = CheckAnswer.CorrectQuestions; 

    Task SendingScores = SendScore.SaveAsync().ContinueWith(t => 
    { 
     if (t.IsFaulted || t.IsCanceled) 
     { 
      DoneSave = false; 
      print(t.Exception); 
     } 
     else 
     { 
      DoneSave = true; 
      print("Setting object ID!"); 
      ScoreObjectId = SendScore.ObjectId; 
      print(ScoreObjectId); 
     } 
    }); 

} 



void SaveTotalTopics() 
{ 
    for (int i = 0; i <= 9; i++) 
    { 
     string Topic = "Topic" + (i + 1).ToString(); 
     SendCorrectTopics[Topic] = CheckAnswer.CorrectTopics[i]; 
    } 

    SendCorrectTopics["UserScore"] = ParseObject.CreateWithoutData("Scores", ScoreObjectId); 
    SendCorrectTopics.SaveAsync().ContinueWith(t => 
    { 
     if(t.IsFaulted || t.IsCanceled) 
     { 
      print(t.Exception); 
     } 
     else 
     { 
      print("Saved!"); 
     } 
    }); 
} 

我還忘了使用ParseObject.CreateWithoutData(),所以我的第一個代碼片段根本不會工作如果我找到一個更好的方法...

所以,本書雖然是呃我對最終結果並不滿意,至少它是有效的,我不認爲每一幀運行if語句都會顯着影響我的遊戲性能。

0
SendScore.SaveAsync().ContinueWith(t => 
{ 
    ScoreObjectId = SendScore.ObjectId; 
}); 

這是您放置任務完成後想要發生的動作的地方。嘗試在ScoreObjectId行下面添加調試來測試它。

+0

是的,我已經測試過了。它肯定會得到ObjectID,但我不確定SaveAsync()是否也返回ObjectID,或者您需要向服務器發送另一個請求。 我學到了很多關於任務和aysnc的知識,只是發現Unity並不喜歡內置的C#函數。現在我的快速修復至少可以工作。不管怎麼說,還是要謝謝你! – FonMasterRyoka

0

爲什麼不使用布爾和while循環?

public IEnumerator SaveScore() 
{ 

    bool canContinue = false; 
    ParseObject SendScore = new ParseObject("Scores"); 
    SendScore["Score"] = CheckAnswer.score; 
    SendScore["user"] = ParseObject.CreateWithoutData("_User", ParseUser.CurrentUser.ObjectId); 
    SendScore["TestMode"] = MainMenu.testmode; 
    SendScore["TotalQuestions"] = QuestionCreation.TotalQuestions; 
    SendScore["CorrectQuestions"] = CheckAnswer.CorrectQuestions; 


    SendScore.SaveAsync().ContinueWith(t => 
    { 
     ScoreObjectId = SendScore.ObjectId; 
     //set the bool canContinue to true because the first portion of code has finished running 
     canContinue = true; 
    }); 

    //wait while the canContinue bool is false 
    while(!canContinue){ 
     yield return null; 
    } 

    //continue your parse code 
    ParseObject SendCorrectTopics = new ParseObject("CorrectAnswers"); 
    SendCorrectTopics["Score"] = SendScore.ObjectId; 
    for (int i = 0; i <= 9; i++) 
    { 
     string Topic = "Topic" + (i + 1).ToString(); 
     SendCorrectTopics[Topic] = CheckAnswer.CorrectTopics[i]; 
    } 

    SendCorrectTopics.SaveAsync(); 

    SceneManager.LoadScene(0); 
    return null; 
} 
+0

感謝您的建議,但我曾嘗試過,並使用while循環導致程序掛起。假設如果主線程被阻塞,它不能更新任何其他線程,所以while循環永遠不會被滿足。我不知道,但我目前的方法工作正常。實質上,一個while循環就是我用於co-routines的東西。 – FonMasterRyoka