【问题标题】:How to wait for a StartCoroutine() to finish before proceeding如何在继续之前等待 StartCoroutine() 完成
【发布时间】:2015-09-16 08:57:40
【问题描述】:

我正在编写一段代码,从 MySQL 获取一条信息并将其显示在 UI 上。问题是,程序不会等待 MySQL 查询完成,而是直接显示变量(这是空的,因为查询的结果没有按时完成)

我的代码的大致轮廓是:

bool notYetDone = true;

StartCoroutine(query(web));

IEnumerator query (WWW web){
    yield return web;
    while(notYetDone == true){
        yield return new WaitForSeconds(1f);
        if(web.error == null){
            //no problems with the query, some code here
            notYetDone = false;
        } else if (web.error != null){
            //some code here for handling errors
        } else {
            Debug.Log("i dont really know why we reached here");
        }
    }
}

我还注意到它似乎改变了notYetDone 的值并立即结束循环。我的代码有问题吗?提前致谢。

【问题讨论】:

  • 尝试使用 web.isDone 而不是 notYetDone == true
  • 直接用 web.isDone 替换 while 参数似乎会产生无限循环。但我会尝试一些使用它的方法。感谢您的建议
  • 如果你使用: while(!web.isDone) 会怎样,所以当它完成时它会为真并退出循环。
  • 我应该在循环中放什么?我只是在等待查询完成
  • while(!web.isDone){ //这将循环直到您的查询完成}if(web.Error == nulll){Debug.log("No errors to display")}else {Debug.Log("Errors on web....")} 我认为这可以工作,现在无法测试,因为我在工作,但是当我有机会时,我可以尝试...跨度>

标签: c# mysql unity3d coroutine


【解决方案1】:

试试这个:

class QueryBehaviour: MonoBehaviour
{
  bool queryFinished = false;
  WWW wwwQuery;

  IEnumerator Query()
  {
    wwwQuery = new WWW("url_to_query");
    yield return wwwQuery;

    queryFinished = true;
    //results or error should be here
  }

  Update()
  {
    if( queryFinished == false )
    {
      return;
    }
    else
    {
      //use wwwQuery here
    }
  }
}

然后只需调用 Query

注意:如果您调用 yield return wwwQuery,则无需忙于等待。如果您不想这样做,您应该忙着等待,例如,您想检查下载进度,在这种情况下,您应该在定义的 Update 方法中轮询 www 类的结果在单一行为

【讨论】:

  • 很抱歉,但它仍然继续到下一行代码。
  • 好的,现在我明白了,是的,它确实进入了下一行代码。该操作是异步的。你需要在 yield 之后设置一个标志,然后你应该有你的查询
  • 你能解释一下这个流程吗?
  • 如果我错了,请纠正我,但据我了解,当 queryFinished 为假时,return 命令将其返回给 query(),如果不是,则查询完成,对吗?跨度>
  • 不完全是。协程由 Unity 运行时异步运行。这意味着在您调用 Query 后,控件将转到流中的下一行。 Unity 调用您返回的 IEnumerator,直到它完成。这意味着 IEnumerator 已完成并且您的协程已完成运行。在更新中,您检查协程是否作为 Unity 完成并没有为此提供另一种机制。
【解决方案2】:

尝试:

IEnumerator query (WWW web)
{
   //yield return web;
   while(!web.isDone && web.Error == null)
   {
    //this will loop until your query is finished
    //do something while waiting...
      yield return null;
   }
   if(web.Error != null)
     Debug.Log("Errors on web");

}

【讨论】:

  • 这是不正确的,有两个原因:yield return web;等待 www 例程的结束就足够了,因此 while 循环是无用的,但如果编码器忘记在 web 上让步,那么它将阻塞线程直到完成。确保您应该完全删除它或在内部产生 null
  • 嗯......你是对的,不需要 while 或者你可以删除 yield return web,并执行类似 while(!web.isDone && web.Error == null){ yield return null}if(error!=null){Debug.Log("Errors on web")},while循环是为了以防万一他想在查询运行时做点什么……
【解决方案3】:

将 yield 关键字放在 startcoroutine 之前也会有同样的效果。在你的情况下:

yield StartCoroutine(query(web)); 
//at this point it is guaranteed to be completed

http://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html

【讨论】:

  • 但是你需要已经在协程中。也许你在想IEnumerator Start() { }
【解决方案4】:

使用回调怎么样?

   public void showMessage(string message)
    {
        setMessage(message);
        Debug.Log("start_fadeIn");
        StartCoroutine(coroutine__fadeIn(delegate
        {
            Debug.Log("start_fadeOut");
            StartCoroutine(coroutine__fadeOut(delegate
            {
                Debug.Log("done");
            }));
        }));
    }


    private IEnumerator coroutine__fadeIn(Action completion)
    {
        CanvasGroup canvasGroup = GetComponent<CanvasGroup>();
        for (float f = 0f; f <= 1; f += 0.01f)
        {
            canvasGroup.alpha = f;
            yield return null;
        }

        completion();
    }

    private IEnumerator coroutine__fadeOut(Action completion)
    {
        CanvasGroup canvasGroup = GetComponent<CanvasGroup>();
        for (float f = 1f; f >= 0; f -= 0.01f)
        {
            canvasGroup.alpha = f;
            yield return null;
        }

        completion();
    }

警告,这种方式需要使用支持 Action 类的 .NET 版本。

【讨论】:

    猜你喜欢
    • 2020-02-24
    • 1970-01-01
    • 2019-03-12
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2020-02-25
    相关资源
    最近更新 更多