Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Awaitable feature requests/bugs

Discussion in 'Experimental Scripting Previews' started by mdsitton, May 10, 2023.

  1. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    After diving into using the new async Awaitable i've noticed a few limitations. First WaitUntil is extremely useful in coroutines so having this officially implemented for Awaitable would remove some boilerplate when migrating code.

    Additionally not having WaitForSecondsRealtimeAsync is a real issue because any code that uses Time.timeScale to pause game play can cause issues when you may be using Awaitable in tandem with any UI code on-top of the game which may be paused. Also before anyone askes the currently supported Awaitable.WaitForSecondsAsync is effected by time scaling.

    @JoshPeterson any thoughts on adding these things?
     
    FoodFish_ likes this.
  2. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    Additionally i've found a bug with:
    await Awaitable.NextFrameAsync();

    When calling Time.timeScale = 0 (i believe on the same frame as the await) it will result in the NextFrameAsync not returning at some point and getting stuck.

    Code (CSharp):
    1.     public async void StartTest()
    2.     {
    3.         Debug.Log("Starting test");
    4.         _statusLine.text = $"Starting test";
    5.         Time.timeScale = 0;
    6.         int frames = 0;
    7.         while (true)
    8.         {
    9.             frames++;
    10.             _statusLine.text = $"Frames {frames} {Time.frameCount}";
    11.             await Awaitable.NextFrameAsync();
    12.         }
    13.     }

    I've reported the bug with a reproduction project: IN-40766
     
  3. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    Hi, WaitUntil can be easily implemented in user code:

    Code (CSharp):
    1. public static async Awaitable(Func<bool> condition, CancellationTokenSource cancellationToken)
    2. {
    3.    while(!condition()){
    4.      cancellationToken.ThrowIfCancellationRequested();
    5.      await Awaitable.WaitForNextFrameAsync();
    6.   }
    7. }
    WaitForSecondsRealtimeAsync would be a welcome addition, right.

    For the timeScale issue, thanks for reporting it. We'll have a look at it.
     
  4. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    Awesome thanks! Also as for the timeScale issue i was told on the report that it was "by design" which doesn't make sense to me so i wouldn't mind some clarification on this.
     
  5. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    Also after playing around with my reproduction project i may have found another bug. Unless I am misunderstanding something here which if that is the case maybe the documentation needs to be clarified.

    Reading the docs here says
    Note: some methods returning an awaitable also accept a CancellationToken. Both cancelation models are equivalent.
    Which leads me to believe that it should be canceling the whole running task and stop execution then return to the caller with an exception. But what i am observing is a bit different.


    Code (CSharp):
    1.     async Awaitable CountFrames()
    2.     {
    3.         int frames = 0;
    4.         while (true)
    5.         {
    6.             frames++;
    7.             _statusLine.text = $"Frames {frames} {Time.frameCount}";
    8.             await Awaitable.EndOfFrameAsync();
    9.         }
    10.     }
    11.  
    12.     Awaitable currentTask = null;
    13.  
    14.     public async void StartTest()
    15.     {
    16.         if (currentTask != null)
    17.         {
    18.             Debug.Log("Cancel test");
    19.             currentTask.Cancel();
    20.             currentTask = null;
    21.             _statusLine.text = "Task canceled";
    22.             return;
    23.         }
    24.         Debug.Log("Starting test");
    25.         _statusLine.text = $"Starting test";
    26.         currentTask = CountFrames();
    27.         await currentTask;
    28.     }
    What happens here is that the CountFrames() task continues running indefinitely and doesn't stop while the caller in StartTest() gets the exception and exits.

    Also i am running unity 2023.1.0b15
     
    Last edited: May 11, 2023
  6. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    Any update on this?
     
  7. kdchabuk

    kdchabuk

    Joined:
    Feb 7, 2019
    Posts:
    47
    If I understand correctly, the code should be:
    Code (CSharp):
    1.     public static async Until(Func<bool> condition, CancellationToken cancellationToken)
    2.     {
    3.        while(!condition()){
    4.          cancellationToken.ThrowIfCancellationRequested();
    5.          await Awaitable.NextFrameAsync();
    6.       }
    7.     }
    Then you can pass in a token with something like:
    Code (CSharp):
    1. cancellationTokenSource = new CancellationTokenSource();
    2. currentTask = Until(myCondition, cancellationTokenSource.Token);
    It's not clear how Awaitable.Cancel() affects the running awaitable itself.

    Edit:
    However you can cancel it by calling
    cancellationTokenSource.Cancel()
     
    Last edited: Jun 28, 2023
  8. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    Yes i could use a cancellation token but the point is that their docs say they should be functionally equivalent and they were not functioning as such
     
    kdchabuk likes this.
  9. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    kdchabuk likes this.
  10. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    WaitUntil, and even WaitUntilCanceled would really valuable feature which would encourage people from making the switch from UniTask framework to Awaitables.

    upload_2023-7-3_8-38-9.png
     
    Last edited: Jul 3, 2023
  11. mdsitton

    mdsitton

    Joined:
    Jan 27, 2018
    Posts:
    63
    Agreed i would very much like to not have to pull in a 3rd party library or write my own implementation for something that should just be in the standard unity library from the beginning
     
    FoodFish_ likes this.