Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Scope 'Task' and 'Task<T>' to components

Discussion in 'Assets and Asset Store' started by Bastian-Blokland, Jul 29, 2019.

  1. Bastian-Blokland

    Bastian-Blokland

    Joined:
    May 14, 2018
    Posts:
    7
    Created a Unity package for running 'Task' and 'Task<T>' scoped to Unity components:
    https://github.com/BastianBlokland/componenttask-unity

    It gives them semantics that are much closer to Unity's Coroutines (paused when the component is disabled and cancelled when the component is destroyed). This avoids all the ugly 'if (!this) return;' checks after every 'await' to guard against the component being destroyed while the task was running.

    Code (CSharp):
    1. using System.Threading.Tasks;
    2. using UnityEngine;
    3.  
    4. class MyClass : MonoBehaviour
    5. {
    6.     void Start()
    7.     {
    8.         this.StartTask(RunAsync);
    9.     }
    10.  
    11.     async Task RunAsync()
    12.     {
    13.         while (true)
    14.         {
    15.             Debug.Log("Running...");
    16.             await Task.Yield();
    17.         }
    18.     }
    19. }
    The above snipped would print 'Running' every frame, pause when disabling the component / gameobject and would stop when destroying the component / gameobject.
     
    NHals likes this.
  2. NHals

    NHals

    Joined:
    Dec 23, 2013
    Posts:
    10
    This seems to solve my remaining issues for converting everything to async in Unity

    Thinking of introducing ComponentTask into my project, but i'm looking for experiences with using this. Is there any pros&cons list anywhere?
     
  3. Bastian-Blokland

    Bastian-Blokland

    Joined:
    May 14, 2018
    Posts:
    7
    We've been using it in our live game for a while and pretty happy so far.

    One issue migrating previous async code was that we unintentionally had quite a bit of code that depended on the task running while the game-object is disabled, so it wasn't plug and play. I'm considering adding some flag that you can give 'StartTask' that will allow the task to run even when the gameobject it is on is disabled (Even though i think its kind of bad practice as its not what you're expecting if you're used to coroutines).

    What i personally love about the Task based async code is that it combines very well with multi-threading, as now code that needs to update some ui can 'await' a task that might be running on a thread-pool thread in a safe way.

    Slightly unrelated but we've been using these helpers in our network layer to fire events from arbitrary threads but allow people to subscribe to those events on the Unity thread. So if you subscribe to the event from the Unity thread you will only be called back on the Unity thread. Makes it very easy to start moving logic to thread-pool tasks incrementally.

    SynchronizedEvent<T>
    https://gist.github.com/BastianBlokland/83941079e413b3f3cff43946afde93d7

    SynchronizedChannel<T>
    https://gist.github.com/BastianBlokland/cd01667cc63b1871bd57bd975c49c2e2
     
  4. NHals

    NHals

    Joined:
    Dec 23, 2013
    Posts:
    10
    Great and confidence inspiring answer. I'm already using Tasks for most async code, but the cancellation token boilerplate is flow-killing and bug creating.

    I will take a look at including this in my project, and will try to leave a review here.

    The SynchronizedEvent is also nice! Will check it out.
     
  5. Bastian-Blokland

    Bastian-Blokland

    Joined:
    May 14, 2018
    Posts:
    7
    Great to hear, really curious to hear how the integration goes.
     
unityunity