Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Unity-仅在协同程序完成后才需要返回值_C#_Unity3d_Coroutine - Fatal编程技术网

C# Unity-仅在协同程序完成后才需要返回值

C# Unity-仅在协同程序完成后才需要返回值,c#,unity3d,coroutine,C#,Unity3d,Coroutine,我在unity做一个游戏,遇到了一个我无法解决的问题。 我通过标准的WWW对象连接到web服务器,并使用一个协同程序来执行POST请求 代码本身可以工作,但我需要更新一个变量值,并在协同程序完成后返回该变量,这是我无法做到的 public int POST(string username, string passw) { WWWForm form = new WWWForm(); form.AddField("usr", username); form.AddField(

我在unity做一个游戏,遇到了一个我无法解决的问题。 我通过标准的WWW对象连接到web服务器,并使用一个协同程序来执行POST请求

代码本身可以工作,但我需要更新一个变量值,并在协同程序完成后返回该变量,这是我无法做到的

public int POST(string username, string passw)
{
    WWWForm form = new WWWForm();
    form.AddField("usr", username);
    form.AddField("pass", passw);

    WWW www = new WWW(url, form);

    StartCoroutine(WaitForRequest(www));

    //problem is here !
    return success_fail;
}

private IEnumerator WaitForRequest(WWW www)
{

    yield return www;
    if (www.error == null)
    {

            if(www.text.Contains("user exists"))
            {

                success_fail = 2;
            }
            else
            {
                success_fail=1;
            }
    } else {
        success_fail=0;
    }    
}
协同程序用相关值更新“success\u fail”的值。 但是“返回成功\返回失败;”POST方法中的行在协同程序完成之前运行,这会导致它返回一个假值

我试图使用一个额外的协同程序,但没有成功,假设我也有一个错误。 如何仅在协同程序完成后返回“success\u fail”值


谢谢。

只有一个协同程序可以等待另一个协同程序。由于您需要等待启动的协程(WaitForRequest),这意味着您必须将POST转换为协程,并且它将无法返回int

看起来success\u fail是一个成员变量,所以如果它向启动POST的人公开(作为一个协同程序),那么无论如何都不需要返回它

public int success_fail

IEnumerator POST(string username, string passw)
{
    WWWForm form = new WWWForm();
    form.AddField("usr", username);
    form.AddField("pass", passw);

    WWW www = new WWW(url, form);

    yield return StartCoroutine(WaitForRequest(www));
}

private IEnumerator WaitForRequest(WWW www)
{
    yield return www;
    if (www.error == null)
    {
        if(www.text.Contains("user exists"))
            {
                success_fail = 2;
            }
            else
            {
                success_fail=1;
            }
    } else {
        success_fail=0;
    }    
}
基本上,如果你想让你的代码“等待”,它必须是一个协同程序。如果不阻塞整个引擎(没有某种类型的循环攻击),就无法进行等待的调用

这个线程提供了一种方法,如果您真的需要,您可以从协同程序返回int,但是POST仍然不能成为阻塞调用


函数在返回之前不会等待协同路由,但是您可以使用操作来给出某种返回

把这个放在你的启动函数中

WWW www = new WWW("http://google.com");

StartCoroutine(WaitForRequest(www,(status)=>{
    print(status.ToString());
}));
再加上这个

private IEnumerator WaitForRequest(WWW www,Action<int> callback) {
    int tempInt = 0;
    yield return www;
    if (string.IsNullOrEmpty(www.error)) {
        if(!string.IsNullOrEmpty(www.text)) {
            tempInt = 3;
        }
        else {
            tempInt=2;
        }
    } else {
        print(www.error);
        tempInt=1;
    }
    callback(tempInt);
}
这可能对你有用。

请参考此网页请求


不要使用
WWW
而是使用
UnityWebRequest

如果您调用另一个协同程序,它将等待该协同程序完成。你混淆了同步和异步代码。也许回调函数会有用?您可以使用
Action
委托,其中
T
是您想要“返回”的任何类型。我尝试了这个方法,但是调用POST as coroutine的方法不会等待在下一行中继续执行。所以它不能解决要更新的
success\u fail
值。@Caco POST应该使用start例程(POST(usename,passw))调用;是的,我使用
startcroutine
调用,但调用后程序流不会停止。在
IEnumerator-POST
方法中,第二个
yield-return
确实停止执行,但第一个没有。听起来正确。协同程序的整体思想是它不会停止执行。您必须调用yield来等待它完成,就像行yield return startcroutine(WaitForRequest(www))一样。您只是在调用堆栈的更高层执行此操作。
StartCoroutine(WaitForRequest(www,(status)=>{
    print(status.ToString());
    Awake(); // we can call other functions within the callback to use other codeblocks and logic.
    if(status != 0)
        print("yay!");
    }
));