Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
620 views
in Technique[技术] by (71.8m points)

c# - Unity - Waiting for HTTP request to resolve

Here is the function, I am wondering if there is a more concise way of writing it:

private static WWW WaitUntilResolved (WWW request)
{
    bool success = true;
    float timeout = 5000, timer = 0;

    while (!request.isDone) {
        if (timer > timeout) {
            success = false;
            break;
        }
        timer += Time.deltaTime;
    }

    if (success && request.error == null)
        return request;
    else {
        request.Dispose ();
        return null;
    }
}

ps. WWW is a native unity class: https://docs.unity3d.com/ScriptReference/WWW.html

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are really using WWW and isDone wrong. If you must use isDone, you must put it in while loop. You must also yield in the while loop with yield return null; otherwise the game will freeze until the download is done. This whole thing requires coroutine so the function must be made a coroutine function.

You really don't need isDone. That's only used when you want to know the progress of the download.

Here is a proper way to use isDone:

private static IEnumerator WaitUntilResolved(WWW request)
{
    while (!request.isDone)
    {
        Debug.Log("Download Stat: " + request.progress);

        //Wait each frame in each loop OR Unity would freeze
        yield return null;
    }

    if (string.IsNullOrEmpty(request.error))
    {
        //Success
    }
}

If you don't need to know the progress of the download then below is something you should use:

private static IEnumerator WaitUntilResolved(WWW request)
{
    yield return request;
    if (string.IsNullOrEmpty(request.error))
    {
        //Success
    }
}

Finally, you cannot call a coroutine function directly. You have to use StartCoroutine function to do that:

WWW www = new WWW("www.yahoo.com");
StartCoroutine(WaitUntilResolved(www));

EDIT:

How do I set a timeout for the coroutine?

Most WebRequest tutorials uses timer. You don't need to do that in Unity with the WWW API. It is not necessary here because this is a non blocking operation. If you must then see the code below.

private static IEnumerator WaitUntilResolved(WWW request)
{
    float timeout = 5000, timer = 0;

    while (!request.isDone)
    {
        Debug.Log("Download Stat: " + request.progress);

        timer += Time.deltaTime;
        if (timer >= timeout)
        {
            Debug.Log("Timeout happened");
            //Break out of the loop
            yield break;
        }
        //Wait each frame in each loop OR Unity would freeze
        yield return null;
    }

    if (string.IsNullOrEmpty(request.error))
    {
        //Success
    }
}

If you need to return the status of the download, see this post that explains how to do that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...