等待foreach中的异步功能

时间:2018-12-20 01:45:51

标签: c# unity3d

在我的项目中,我尝试使用不同的IP地址进行连接。如果无法连接,我将切换到下一个IP

foreach(var handler in webHandlers)
{
    if(handler.TryConnect())
    {
        handler.Init();
        break;
    }
}

处理程序类:

bool finished = false;
bool returnval = false;

public bool TryConnect()
{
    StartCoroutine(TryConnection);
    while(!finished) { }
    return returnval;
}
IEnummerator TryConnection()
{
    UnityWebRequest www = UnityWebRequest.Get("url");
    www.timeout = 5;
    yield return wwww.SendWebRequest();
    if(www.isNetworkError)
    {
        returnval = false;
    }
    {
        returnval = true;
    }
    finished = true;
}

如果有连接,它会立即起作用。但是,如果找不到它,团结就会崩溃。成品的价值似乎从未改变。游戏阻塞并不重要,因为这应该在开始游戏之前完成。

我的问题是,如何在等待协程结果的情况下解决此问题。

2 个答案:

答案 0 :(得分:0)

使用while(!finished){}时将阻塞主线程。更好您应该在另一个脚本中移动协程。即您的处理程序可用的地方。并在协程中要求每个处理程序。如果连接不可用,则继续下一个协程实例中的下一个处理程序。

您可以检查已修改的功能。该函数是根据您的代码编写的粗略代码段,它将继续检查连接,直到它连接到任何一个处理程序或用尽了这些处理程序为止。

public IEnumerator TryConnection(int index)
{
    if (handlers.count > index)
    {
        //Get next handler here
        Handler handler = handlers[index];
        UnityWebRequest www = UnityWebRequest.Get(handler.url);
        www.timeout = 5;
        yield return www.SendWebRequest();
        if (www.isNetworkError)
        {
            StartCoroutine(TryConnection(index++));
        }
        else
        {
            handler.init();
        }
    }        
}

请记住将TryConnection移到您可以使用处理程序列表的位置。

答案 1 :(得分:0)

我实际上找到了一种非常简单和清洁的方式

public bool TryConnect()
{
    WebRequest request = WebRequest.Create(url);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    return response.StatusCode == HttpStatusCode.OK;
}

由于它不是在协程上运行,因此代码只是等待直到收到响应为止。这也比统一版本快很多。由于所有这些都是在主线程中调用的,因此游戏甚至在启动之前都等待响应。超时时间最多为一秒钟,因此它不会阻止游戏(就像unity的连接超时一样)