2016-01-10 223 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