在foreach循环Unity3D C#中的协程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在foreach循环Unity3D C#中的协程相关的知识,希望对你有一定的参考价值。

大家!

我正在尝试使用foreach上传多个文件。到目前为止,我已成功上传所有内容,但我想先完成协程,然后继续进行for循环中的下一项bc我将要进行进度条。由于某种原因,协同程序都是在一个而不是一个一个地执行。

这是我的代码:

    public void CallUploadFile() //Called by button
    {
        StartCoroutine(UploadScene());
    }

    IEnumerator UploadScene()
    {
        foreach(string str in item_list)
        {
            string item_path = str;
            yield return new StartCoroutine(StartUpload (item_path));
        }
    }

    IEnumerator StartUpload(string item_path)
    {
         byte[] image_bytes;
         image_bytes = File.ReadAllBytes(item_path);

         // upload using WWWForm;
        WWWForm form = new WWWForm ();
        form.AddBinaryData ("scene[image]", image_bytes);
        using (UnityWebRequest www = UnityWebRequest.Post("somelink.com/upload", form))
        {
             yield return www.Send();
            while (!www.isDone)
            {
               Debug.Log(www.progress);
               yield return null
            }
            Debug.Log("Success!");
        }
    }

我已在各种论坛上阅读过有关此主题的内容,此代码应该可以正常工作,但由于某些原因,这种方法无法正任何抬头都会非常感激。

答案

使用下面的代码:这将使返回null之前的所有代码完成,这符合您的需要。

IEnumerator UploadScene()
{
    foreach(string str in item_list)
    {
        string item_path = str;
        StartUpload (item_path));
    }
    yield return null;   //returns until work is done.
}

void StartUpload(string item_path)
{
     byte[] image_bytes;
     image_bytes = File.ReadAllBytes(item_path);

     // upload using WWWForm;
}
另一答案

你的外部枚举可以产生内部的枚举

IEnumerator UploadScene()
{
    foreach(string str in item_list)
    {
        string item_path = str;
        yield return StartUpload (item_path);
    }
}

编辑:我在文档中找不到send方法,qazxsw poi

你确定它会返回收益指令吗?你可以跳过它,只使用yield return null而不是完成代码

edit2:有一个异步SendWebRequest方法。其返回值与Coroutines不兼容。

另一答案

我认为你的代码工作正常,但你打印错了。

https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.html

一旦前一个协同程序结束,你正在准备好开始每个协同程序。到目前为止,我会说这么好。

IEnumerator UploadScene()
{
    foreach(string str in item_list)
    {
        string item_path = str;
        yield return new StartCoroutine(StartUpload (item_path));
    }
}

你正在放弃发送请求,这将在某种程度上“停止”协程,直到下载完全完成。接下来,如果没有完成,请打印,但直到下载结束为止。

所以我希望你只有成功的印刷。

你需要的是在循环中产生:

IEnumerator StartUpload(string item_path)
{
     // Code
    using (UnityWebRequest www = UnityWebRequest.Post("somelink.com/upload", form))
    {
         yield return www.Send();
        while (!www.isDone)
        {
           Debug.Log(www.progress);
           yield return null
        }
        Debug.Log("Success!");
    }
}

这将调用发送请求并将继续。但现在它将在while循环util中产生,因此它将逐个打印进度。

请记住,这会使您的下载时间更长。您可以在同一个循环中触发它们,然后Unity将启动不同的线程(不是协同程序,正确的线程),因此您可以并行进行多次下载。

以上是关于在foreach循环Unity3D C#中的协程的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D的协程1——初步理解背后的迭代器

协程由两个带 while循环的函数和yield组建的协程

比物理线程都好用的C++20的协程,你会用吗?

Python 中的协程 yield from

c语言实现的协程

在循环中使用协程