C# Unity-等待HTTP请求解析

C# Unity-等待HTTP请求解析,c#,unity3d,C#,Unity3d,下面是函数,我想知道是否有更简洁的方法来编写它: private static WWW WaitUntilResolved (WWW request) { bool success = true; float timeout = 5000, timer = 0; while (!request.isDone) { if (timer > timeout) { success = false; brea

下面是函数,我想知道是否有更简洁的方法来编写它:

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;
    }
}

WWW是一个原生的统一类:

你真的在使用
WWW
而且是错误的。如果必须使用
isDone
,则必须将其置于while循环中。您还必须在while循环中使用
yield返回null否则游戏将冻结,直到下载完成。这整件事都需要,所以该函数必须成为一个协程函数

你真的不需要
isDone
。只有当您想知道下载进度时,才使用

以下是使用
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
    }
}
如果您不需要知道下载的进度,那么以下是您应该使用的内容:

private static IEnumerator WaitUntilResolved(WWW request)
{
    yield return request;
    if (string.IsNullOrEmpty(request.error))
    {
        //Success
    }
}
最后,您不能直接调用协程函数。您必须使用函数来执行此操作:

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

编辑:


如何设置协同程序的超时

大多数
WebRequest
教程都使用计时器。您不需要与
WWW
API结合使用。这里不需要,因为这是一个非阻塞操作。如果您必须查看下面的代码

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
    }
}

如果您需要返回下载状态,请参阅解释如何返回的帖子。

您确实使用了
WWW
,但这是错误的。如果必须使用
isDone
,则必须将其置于while循环中。您还必须在while循环中使用
yield返回null否则游戏将冻结,直到下载完成。这整件事都需要,所以该函数必须成为一个协程函数

你真的不需要
isDone
。只有当您想知道下载进度时,才使用

以下是使用
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
    }
}
如果您不需要知道下载的进度,那么以下是您应该使用的内容:

private static IEnumerator WaitUntilResolved(WWW request)
{
    yield return request;
    if (string.IsNullOrEmpty(request.error))
    {
        //Success
    }
}
最后,您不能直接调用协程函数。您必须使用函数来执行此操作:

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

编辑:


如何设置协同程序的超时

大多数
WebRequest
教程都使用计时器。您不需要与
WWW
API结合使用。这里不需要,因为这是一个非阻塞操作。如果您必须查看下面的代码

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
    }
}

如果需要返回下载状态,请参阅解释如何返回的帖子。

下面是等待异步调用的示例

string WebGet()
{
    Response result = new Response();
    IEnumerator e = GetStuff(result);

    // blocks here until UnityWebRequest() completes
    while (e.MoveNext());

    Debug.Log(result.result);
}

public class Response
{
    public string result = "";
}

IEnumerator GetStuff(Response res)
{
    UnityWebRequest www = UnityWebRequest.Get("http://some.add.com/");

    yield return www.SendWebRequest();

    while (!www.isDone)
        yield return true;

    if (www.isNetworkError || www.isHttpError)
        res.result = www.error;
    else
        res.result = www.downloadHandler.text;
}

下面是一个等待异步调用的示例

string WebGet()
{
    Response result = new Response();
    IEnumerator e = GetStuff(result);

    // blocks here until UnityWebRequest() completes
    while (e.MoveNext());

    Debug.Log(result.result);
}

public class Response
{
    public string result = "";
}

IEnumerator GetStuff(Response res)
{
    UnityWebRequest www = UnityWebRequest.Get("http://some.add.com/");

    yield return www.SendWebRequest();

    while (!www.isDone)
        yield return true;

    if (www.isNetworkError || www.isHttpError)
        res.result = www.error;
    else
        res.result = www.downloadHandler.text;
}

您的代码在轮询循环中被阻塞。这是非常不可取的。有什么原因不能使用非阻塞异步
HttpClient
类吗?我对Unity不太熟悉,
WWW
是Unity中的类还是其他什么?另外,请在上下文中发布您的代码。什么代码正在调用
waituntillresolved
?你有多个线程吗?Unity在他们的教程中有这个。您应该使用枚举器。您的代码在轮询循环中被阻塞。这是非常不可取的。有什么原因不能使用非阻塞异步
HttpClient
类吗?我对Unity不太熟悉,
WWW
是Unity中的类还是其他什么?另外,请在上下文中发布您的代码。什么代码正在调用
waituntillresolved
?你有多个线程吗?Unity在他们的教程中有这个。您应该使用枚举器。我如何设置协同程序的超时时间?@Ja.L你不需要超时。仅当
WWW
不异步时才需要它。有关更多信息,请参阅编辑后的答案。如果我将返回类型设置为IEnumerator,则我无法再返回WWW对象?否。不能直接返回,因为它必须是
IEnumerator
。尽管我在答案的末尾提供了一个链接,显示了如何返回一个以
Action
作为参数的值。您可以添加
操作
作为额外参数。我链接的示例从与
Action reqStat
的协同程序返回
bool
,但您可以使其返回
WWW
Action reqStat
。我会让你去做的。我应该在超时/出错时调用WWW.dispose(),还是没有必要?我如何设置协同程序的超时?@Ja.L你不需要超时。仅当
WWW
不异步时才需要它。有关更多信息,请参阅编辑后的答案。如果我将返回类型设置为IEnumerator,则我无法再返回WWW对象?否。不能直接返回,因为它必须是
IEnumerator
。尽管我在答案的末尾提供了一个链接,显示了如何返回一个以
Action
作为参数的值。您可以添加
操作
作为额外参数。我链接的示例从与
Action reqStat
的协同程序返回
bool
,但您可以使其返回
WWW
Action reqStat
。我将把这留给你去做。我应该在超时/出错时调用WWW.dispose(),还是没有必要?我尝试了这个,但给出了
未捕获的异常:abort(“无法放大内存数组”
…我尝试了这个,但给出了
未捕获的异常:abort(“无法放大内存数组”
)。。。