Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Async/await and webgl builds

Discussion in 'Experimental Scripting Previews' started by kiyakkoray, May 27, 2017.

  1. DrViJ

    DrViJ

    Joined:
    Feb 9, 2013
    Posts:
    163
    @stonstad I have some news for you.
    I dont know how, but I have successfully built the threads enabled project.

    What does the program do:

    The results:
    Sometimes program freezes, it looks like race condition or something similar. I have 100% CPU usage and program freeze. No Cut result in this situation:
    100 Cpu Race condition maybe.PNG

    Sometimes I get outofmemory errors, like in one of your posts:
    Some of the errors in console and alert log: (they can have little difference from time to time)
    error4.PNG Error1.PNG error3.PNG

    And rarely the result is successfull:
    successfull cut.PNG

    Built in Unity 2020.1.0f1
    The build tested in Chrome version 84.0.4147.125, 64 bit
    Desktop builds work successfull in same situations. But I think I should try more simple tests for this api, cause I have no idea how to debug this :D
     
    Last edited: Aug 17, 2020
  2. DrViJ

    DrViJ

    Joined:
    Feb 9, 2013
    Posts:
    163
    I am very sorry for spamming the forum. I've got one more interesting error.

    One new error.PNG
     
    Last edited: Aug 17, 2020
  3. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    Your earlier post helped me to get my code stable! Thank you! Although I had replaced all instances of System.Threading.Task.Run earlier, I still had a few UniTask.Run statements that I didn't realize were operating on the Unity threadpool. When I changed this code to coroutines random memory access / buffer errors stopped appearing.

    When the unintentional threading was enabled I also saw strange (and random) casting errors similar to what you describe above.

    Here is a summary of the issues I encountered with WebGL threading enabled:
    • async/await works -- but you must be absolutely certain that no threading exists otherwise random failures will occur.
    • any class which depends on system.threading will likely fail randomly. This includes concurrent collections, such as ConcurrentDictionary and ConcurrentQueue.
    • Using generics and inheritance can cause runtime AOT compilation issues that won't be accurately reported unless you are including debugging symbols.
    • External libraries which expose async/await interfaces likely use threading and won't work reliably. In my case I had to replace HttpClient (.NET library, built-in) with the Best HTTP plugin and replace all instances of System.Threading.Task with UniTask.
     
    Julien-Lynge and DrViJ like this.
  4. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    @DrViJ Are you able to use System.Linq without error when threading is enabled?
     
  5. DrViJ

    DrViJ

    Joined:
    Feb 9, 2013
    Posts:
    163
    @stonstad Yes, I did not notice any problems with Linq usage. Maybe you can show an example to try to reproduce.
     
  6. brendanduncan_u3d

    brendanduncan_u3d

    Unity Technologies

    Joined:
    Jul 30, 2019
    Posts:
    437
    @DrViJ I'm currently working on the crashes with "PlayerSettings.WebGL.threadsSupport = true". Obviously an area I need to add more tests for, to keep those instabilities from leaking out. I should have it fixed soon.
     
    bdovaz and DrViJ like this.
  7. DrViJ

    DrViJ

    Joined:
    Feb 9, 2013
    Posts:
    163
    these are great news! thank you for your work! :)
     
    Last edited: Aug 30, 2020
  8. brendanduncan_u3d

    brendanduncan_u3d

    Unity Technologies

    Joined:
    Jul 30, 2019
    Posts:
    437
    Some recent changes to IL2CPP indirectly broke the thread support for WebGL (by exposing a bug in Emscripten). We are working hard on integrating a newer Emscripten that will fix the issue, but it's taking some time. Wanted to let you know if it's taking a while, it's not because we're ignoring it.
     
    tobiass and DrViJ like this.
  9. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    @brendanduncan_u3d Much appreciate the update. We have a WebGL application that is ready for production release. Our only blocker at this time is WebGL stability -- we get many of the random errors described above.
     
  10. DrViJ

    DrViJ

    Joined:
    Feb 9, 2013
    Posts:
    163
  11. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    PS-JimmyAlger and DrViJ like this.
  12. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    @DrViJ I'm not any closer to finding stability. I converted UniTask coroutines to vanilla Unity coroutines with enumerators which are then awaited using GetAwaiter(). I don't get errors with stack traces as often as I get freezes. The WebGL player just freezes and the tab or whole browser must be closed.
     
  13. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    @JoshPeterson
    I have small question.
    Does Unity team have any plan to improve async/await support in webgl with single thread?
    For example make System.Threading.ThreadPool with just one thread (like in mono-wasm and Blazor) and/or reimplement System.Threading.Timer.
     
    stonstad and DerrickBarra like this.
  14. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    I'm not aware of any plans, but I'll defer to @brendanduncan_u3d, since he is on the WebGL team.
     
    DrViJ and VolodymyrBS like this.
  15. Argument

    Argument

    Joined:
    Jul 5, 2015
    Posts:
    20
    Hello.

    Can you tell me any news on the progress of the fix? Is the issue in 2019.4.x not resolved?
     
    DrViJ likes this.
  16. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    DrViJ and Argument like this.
  17. Maras

    Maras

    Joined:
    Dec 11, 2012
    Posts:
    131
    Async/Await works for me in 2019.4, but can't use Task.Delay (as mentioned in this thread). I replaced it with the code below.

    Code (CSharp):
    1.     public static async Task DelayAsync(float secondsDelay)
    2.     {
    3.         float startTime = Time.time;
    4.         while (Time.time < startTime + secondsDelay) await Task.Yield();
    5.     }

    The remaining functionality such as Task.Yield seems to work.
     
  18. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    A small package that makes it possible to use more Task functionality without worrying that something will be scheduled to other threads.
    This package patch some BCL types to make it possible:
    - ThreadPool implementation is changed to use only one available thread.
    - Timer implementation is changed to use js timers. This makes Task.Delay safe to use

    https://github.com/VolodymyrBS/WebGLThreadingPatcher.git
     
    Last edited: Jun 1, 2021
  19. spatialwb

    spatialwb

    Joined:
    Sep 26, 2019
    Posts:
    12
    @VolodymyrBS Is this case supposed to work with your plugin?


    Code (CSharp):
    1. public class App : MonoBehaviour
    2. {
    3.     void Start()
    4.     {
    5.         AwaitTask();
    6.     }
    7.  
    8.     private async void AwaitTask()
    9.     {
    10.         Debug.Log($"AwaitTask started");
    11.         await Task.Run(() => {
    12.             Debug.Log($"inside Task.Run");
    13.         });
    14.         Debug.Log($"After await Task.Run");
    15.     }
    16. }
    I only see the first log
     
  20. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    Yes, this should work.
    What Unity version did you use?
     
  21. spatialwb

    spatialwb

    Joined:
    Sep 26, 2019
    Posts:
    12
    @VolodymyrBS For this test I was on 2020.2.1f1, but my larger project that I want to integrate this in, is on 2020.1.14f1
     
  22. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    brendanduncan_u3d any we will get special BCL implementation in WebGL?
    For instance, I mean:
    - ThreadPool with one thread;
    - Timer based on js engine capabilities and not on the additional thread;
    - HttpMessageHandler rewrote to work based on js engine capabilities.

    A similar approach already used in Blazor WASM. With such BCL we could use almost any .NET assembly without worry.
    IMO there good chance to do so while updating Unity BCL to .NET Standard 2.1 / .NET 6
     
  23. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    Hey, I'd really like this plugin (wrote you on GitHub). Can you take a look into updating it to work with unity 2021?
     
    _TheFuture_ likes this.
  24. xucian

    xucian

    Joined:
    Mar 7, 2016
    Posts:
    846
    I can confirm @VolodymyrBS made it work and I'm currently using async/await with UniTask flawlessly, Unity 2021.3.6 The library actually is quite advanced and lots of work was put into it. I highly recommend it!
     
    brendanduncan_u3d likes this.
  25. tonkodonis

    tonkodonis

    Joined:
    Aug 21, 2022
    Posts:
    5
    could you please elaborate how you made this change practically ? I just replaced Task.Delay(5000) by Task.Yeld(5000) but does not seem to work...
     
  26. Samuele_Angeletti

    Samuele_Angeletti

    Joined:
    Jan 23, 2021
    Posts:
    4
    GDevTeam likes this.
  27. Marks4

    Marks4

    Joined:
    Feb 25, 2018
    Posts:
    548
    Thanks for this one.
     
    xucian likes this.