C# 正在Unity3D中等待parse.com异步任务完成

C# 正在Unity3D中等待parse.com异步任务完成,c#,asynchronous,parse-platform,unity3d,C#,Asynchronous,Parse Platform,Unity3d,作为我学校项目的一部分,我试图链接两个表以减少存储在一个表中的数据量,因此我想通过ObjectID将我的“分数”类与我的“正确答案”类链接起来。但是,由于任务是异步的,当一个任务完成保存时,另一个任务已经开始或也完成了保存,因此ObjectID返回为null 以下是我使用的代码: public void SaveScore() { ParseObject SendScore = new ParseObject("Scores"); SendScore["Score"] = Ch

作为我学校项目的一部分,我试图链接两个表以减少存储在一个表中的数据量,因此我想通过ObjectID将我的“分数”类与我的“正确答案”类链接起来。但是,由于任务是异步的,当一个任务完成保存时,另一个任务已经开始或也完成了保存,因此ObjectID返回为null

以下是我使用的代码:

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);
}
public void SaveScore()
{
ParseObject SendScore=新的ParseObject(“分数”);
SendScore[“Score”]=CheckAnswer.Score;
SendScore[“user”]=ParseObject.createwithout数据(“\u 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=新的ParseObject(“CorrectAnswers”);
SendCorrectTopics[“Score”]=SendScore.ObjectId;

对于(int i=0;iEDIT:ok,在进一步阅读Unity的协同程序之后,我发现了一种更好的检查方法,它只在需要时依赖于检查:

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

}
这似乎是一个更好的方法

嗯,看来答案是我以前做过的,即使有点难看

我使用Unity的更新函数创建了一个检查,以确保ObjectID不为null,并且上一次保存已完成,如下所示:

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!");
        }
    });
}
public void SaveScore()
{
ParseObject SendScore=新的ParseObject(“分数”);
SendScore[“Score”]=CheckAnswer.Score;
SendScore[“user”]=ParseObject.createwithout数据(“\u user”,ParseUser.CurrentUser.ObjectId);
SendScore[“TestMode”]=MainMenu.TestMode;
SendScore[“TotalQuestions”]=QuestionCreation.TotalQuestions;
SendScore[“CorrectQuestions”]=CheckAnswer.CorrectQuestions;
任务发送核心=SendScore.SaveAsync().ContinueWith(t=>
{
如果(t.IsFaulted | | t.IsCanceled)
{
DoneSave=假;
打印(t.Exception);
}
其他的
{
DoneSave=true;
打印(“设置对象ID!”);
ScoreObjectId=SendScore.ObjectId;
打印(ScoreObjectId);
}
});
}
void SaveTotalTopics()
{
对于(int i=0;i
{
如果(t.IsFaulted | | t.IsCanceled)
{
打印(t.Exception);
}
其他的
{
打印(“已保存!”);
}
});
}
我还忘了使用ParseObject.CreateWithoutData(),所以即使我找到了更好的方法,我的第一个代码片段也不会工作


因此,尽管我对最终结果不满意,但至少它是有效的,而且我不认为每帧运行一个if语句都会对我的游戏性能产生显著影响。

为什么不使用bool和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;
}
public IEnumerator SaveScore()
{
bool-canContinue=false;
ParseObject SendScore=新的ParseObject(“分数”);
SendScore[“Score”]=CheckAnswer.Score;
SendScore[“user”]=ParseObject.createwithout数据(“\u user”,ParseUser.CurrentUser.ObjectId);
SendScore[“TestMode”]=MainMenu.TestMode;
SendScore[“TotalQuestions”]=QuestionCreation.TotalQuestions;
SendScore[“CorrectQuestions”]=CheckAnswer.CorrectQuestions;
SendScore.SaveAsync().continue(t=>
{
ScoreObjectId=SendScore.ObjectId;
//将bool canContinue设置为true,因为代码的第一部分已完成运行
canContinue=true;
});
//等待canContinue布尔为false
而(!canContinue){
收益返回空;
}
//继续解析代码
ParseObject SendCorrectTopics=新的ParseObject(“CorrectAnswers”);
SendCorrectTopics[“Score”]=SendScore.ObjectId;

对于(int i=0;我有一个想法…作为“Fon Masta”在解析时,您必须进入服务器代码。尝试一下,这很容易开始。感谢您的建议,但我已经尝试过了,使用while循环会导致程序挂起。假设主线程被挂起,它无法更新任何其他线程,因此while循环永远不会得到满足。我不知道,但我当前的方法是很好。本质上,while循环是我在co例程中使用的。