2017-06-21 112 views
1

下面是函數,我想知道是否有寫它的一個更簡潔的方式:團結 - 等待HTTP請求解決

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是一個本地統一類:https://docs.unity3d.com/ScriptReference/WWW.html

+0

您的代碼在輪詢循環中被阻塞。這非常不可取。有沒有理由不能使用非阻塞異步'HttpClient'類? – Dai

+0

我對Unity不太熟悉,在WWW中是Unity還是其他的類? – Dai

+0

此外,請在上下文中發佈您的代碼。什麼代碼調用'WaitUntilResolved'?你有多個線程正在進行嗎? – Dai

回答

3

你真的使用WWWisDone錯誤。如果您必須使用isDone,則必須將其置於while循環中。你也必須在yield return null;的while循環中輸出,否則遊戲將凍結,直到下載完成。這整個事情需要coroutine所以該功能必須作爲協同功能。

你真的不需要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 
    } 
} 

最後,你不能直接調用協程函數。你必須使用StartCoroutine功能來做到這一點:

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

編輯:

如何設置的協程超時?

大多數WebRequest教程使用計時器。你不需要在Unity中使用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 
    } 
} 

如果您需要返回下載的狀態,看到this後,解釋如何做到這一點。

+0

如何爲協程設置超時? –

+0

@ Ja.L你**不需要超時。如果'WWW'不是異步的,你只需要它。有關更多信息,請參閱編輯答案。 – Programmer

+0

如果我將返回類型設置爲IEnumerator,那麼我不能再返回一個WWW對象? –