关于c#:Unity-仅在协程完成后才需要返回值

Unity - need to return value only after coroutine finishes

我正在统一开发游戏,遇到了无法解决的问题。
我正在通过标准WWW对象并使用协程连接到Web服务器,以执行POST请求。

代码本身可以工作,但是我需要更新一个变量值,并在协程完成后返回该变量,而我无法执行此操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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_fail"的值。
但是"返回成功失败"; 协程完成之前,POST方法中的代码行会运行,这会导致它返回错误的值。

我尝试使用其他协程,但未成功,假设我也有错误。
如何仅在协程完成后才能返回" success_fail"值?

谢谢。


函数不等待协程返回,但是您可以使用Action进行某种返回。

把它放在你的启动功能中

1
2
3
4
5
WWW www = new WWW("http://google.com");

StartCoroutine(WaitForRequest(www,(status)=>{
    print(status.ToString());
}));

并添加它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
}

尝试一下,尽管函数可以更改值,但它不返回值,而只有一个参数。因此,从本质上讲,这不是返回协程的解决方案,但是,一旦从协程接收到int,我们便可以证明对其进行处理的理由,甚至可以从回调内调用其他函数。

1
2
3
4
5
6
7
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!");
    }
));

这可能对您有用。
http://answers.unity3d.com/questions/744888/returning-an-ienumerator-as-an-int.html


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

看起来success_fail是成员变量,所以如果暴露给启动POST的人(作为协程),则无论如何都不需要返回它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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仍然不能成为阻塞调用...

http://answers.unity3d.com/questions/24640/how-do-i-return-a-value-from-a-coroutine.html