Search Unity

Is UnityWebRequest threaded to background?

Discussion in 'Scripting' started by eppz, Jan 25, 2018.

  1. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    I can see that it has IEnumerators to be used in Coroutines.

    I'm asking if the code between the yields is running on a separate background thread, or still blocking the main thread.

    The predecessor (WWW) was also Coroutine based, but still the calls between yields freezed the main thread. It is really annoying, when a web service is lagging / not available.
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Coroutines run on the main thread, unless you implement a mechanism that allows to jump back and forth between threads.
    Back to the usual coroutines: If your coroutine keeps "freezing" your main thread, you're either executing a very expensive piece of code, you're hanging in a loop or you're calling a blocking operation.
     
  3. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    Thanks for getting back!

    It is not me in some cases: a while back a 3rd party analytics we used were implemented using WWW calls, that had the game frozen every minute as they dispatched a vast amount of analytics events.

    Coroutines are just kind of a neat helper, but they are basically calls on the main thread on every frame. If you put in a System.Threading.Thread.Sleep(5000); in any Coroutine, the game will freeze for 5 seconds. This kind of stuff does not happen, if you process heavy stuff on a background thread.

    And I definitely want my networking that kind of stuff. If UnityWebRequest is running on the main thread, then it is not for me either. For now, RestSharp seems fine: it uses .NET APIs nicely dispatched to a background thread.

    Anyway, I'm still curious whether UnityWebRequest is requesting on a background thread, or not.
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    That's what I said above. Everything you put there (unless you do thread jumping) is executed on the main thread.

    Now in order to benefit from coroutines, the web requests are surely run in the background in parallel. The async operation you keep yielding is implemented in such a way that it polls an internal state. Once the request finished, the state changes and with the following state query, the yielding of that operation will be complete and the program will be allowed to proceed.

    If it wasn't using any backgrond thread, you'd totally block the main thread by sending a request, which would render the usage of coroutines ineffective and superfluous.

    You could even write your own yield instruction (CustomYieldInstruction or a plain IEnumerator) and do that in your own way.
     
    eppz likes this.
  5. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    In short: I've seen WWW classes blocking the main thread, so I don't prefer using them. I'm just asking whether UnityWebRequest is the same. I'm hoping for an answer from someone who is involved in implementing UnityWebRequest (sure it won't download 1 GB synchronously, but polling for progress, or network reachability / IP availablility / whatever network test still could be main threaded somewhere within).

    Anyway, RestSharp is threaded by default, also the API is kind of intuitive, like below.
    Code (CSharp):
    1. var client = new RestClient("http://maps.googleapis.com");
    2. var request = new RestRequest("maps/api/geocode/json", Method.GET);
    3. request.AddParameter("address", "Siofok");
    4. var handle = client.ExecuteAsync(request, response =>
    5. { Debug.Log(response.Content); });
     
    Last edited: Jan 26, 2018
  6. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    UnityWebRequest is threaded under the hood, all download happens on other thread, you can poke it for progress from main thread, while the downloaded data is only accessible from main thread.
    WWW is a wrapper on top of UnityWebRequest since 2017.1 and it was also threaded before that. It, however, has a downside that if you access downloaded data in a fancy way (like taking texture from WWW), it will block main thread for the time of doing data processing (i.e. creating texture from raw bytes).
     
    senjacob, eppz and Suddoha like this.
  7. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    @Aurimas-Cernius Yay, thanks for the information! Is it still hooked up to NSURLRequest / NSURLConnection / NSOperationQueue classes on iOS? Or is it using .NET WebRequest classes on every platform?
     
    Last edited: Jan 26, 2018
  8. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    Today I made a tons of test with measuring CPU time / with various server response times / concurrency / network availability, and saw no significant amount of lag indeed.
     
  9. Chris-HG

    Chris-HG

    Joined:
    Aug 10, 2012
    Posts:
    63
    What platforms is RestSharp compatible with?
     
  10. eppz

    eppz

    Joined:
    Aug 2, 2014
    Posts:
    172
    @Chris-HG iOS, Android, Windows Phone, and probably more. I don't know exactly, lookup their resources.

    However, RestSharp complicates main thread calls somewhat from async callbacks, so after I made the corresponding test, I've stuck with UnityWebRequest.
     
  11. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Just write a very generic dispatcher and trigger it in a thread-safe manner every x frames or x seconds. :)
    That does only make sense though if you really prefer RestSharp over Unity's implementation. As an alternative, you could see this as an opportunity to give some valuable feedback about your concerns or issues with the current implementation. :)
     
  12. JotaRata

    JotaRata

    Joined:
    Dec 8, 2014
    Posts:
    61

    There is a way to control the number of threads of any WebRequest operation?
     
  13. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    No.