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

Unity Future .NET Development Status

Discussion in 'Experimental Scripting Previews' started by JoshPeterson, Apr 13, 2021.

  1. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    Yea that certainly went off the rails quickly. Perils of posting in General, I suppose.


    On-topic, I'm wondering if the .NET 7 AoT is on the radar to fit into (probably distant) future plans, as a possible new back end alongside Mono, CoreCLR and IL2CPP. Not sure if it has any serious limitations that would preclude its usage with Unity (and it doesn't seem to support many platforms right now). I know that Unity maintains its own runtime library for IL2CPP, so wondering if using .NET AoT would take that load off long term.
     
    TangerineDev and cxode like this.
  2. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    I've and others have asked that already because we were wondering the same thing. Essentially since it only supports relatively few platforms yet, they won't do it soon, but they will keep an eye on AOT's development.
     
    TangerineDev, Iron-Warrior and cxode like this.
  3. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    Can't believe how there are such people even existing. Was a pain reading through the thread after the first few normal messages. Am definitely also of the opinion that source should be available for all. For the betterment of the Unity in general.
     
  4. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    548
    I mean y’all made me curious and WOW XD
    my favorite :’)
     
    TangerineDev likes this.
  5. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    As update itself returns an Awaitable that is never awaited, the instance is not put back to the pool. This is the one that appears in the allocation (as it is not pooled back, you get an awaitable instance allocated per call to Update).

    I think in that case, async void would be the best alternative.
     
    CaseyHofland likes this.
  6. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    548
    Could all of this quote be added to the docs?
     
  7. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    Following up on the post by @Mindstyler, we don't think that Native AOT is ready for production use yet (it only supports Windows and Linux at .NET 7). But we're using it internally a bit to get some experience, and we're watching its development.

    Our current plan is to continue to support IL2CPP as an AOT runtime, but use the BCL from dotnet/runtime with it. We'll see how Native AOT progresses though. It may be an option in the future.
     
  8. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Oh, I already tried that too before and it allocates twice as much (or x4 more than IEnumerator)

    Are any other callbacks awaited (like OnEnable, Start, OnDestroy etc)?

    Hopefully what I said half year ago won't be true but so far UniTask seems to be better than Awaitable.

    Requirement to await is pretty limiting. What if I want to add callback to let's say a button or an event? Or simply not await on purpose to continue my logic. For ex. let something run in the background, possibly on another thread? Often I do something like:
    Code (CSharp):
    1. void Start()
    2. {
    3.     // some logic
    4.     LoadImage(myImg, image).Forget(); //don't await, it may take long time
    5.     LoadImage(myImg2, image2).Forget();
    6.     // continue
    7. }
    8. async UniTask LoadImage(string imagePath, Image image)
    9. {
    10.     var tex = await UWRAsync.GetTexture(imagePath);
    11.     //obj may be destroyed before img loaded
    12.     if (tex != null && image != null)
    13.     {
    14.         image.texture = tex;
    15.     }
    16. }
     
    MasonWheeler likes this.
  9. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    The same "Forget" extension method can be done on Awaitable for this purpose.
     
    bdovaz likes this.
  10. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Not really as it allocates even if awaited in different place. Maybe some weird Func<Awaitable> would work but that's too cumbersome to use.
     
    oscarAbraham likes this.
  11. simon-ferquel-unity

    simon-ferquel-unity

    Unity Technologies

    Joined:
    Apr 1, 2021
    Posts:
    65
    Oh Indeed, you are right.

    I don't think we'll introduce an equivalent of UniTaskVoid as actually AsyncVoidMethodBuilder does not seem to allocate in .net Core and we are moving towards it.

    However, I have a naive implementation (not thread safe) of an async method builder that does not allocate that could be used in replacement of async void:

    Code (CSharp):
    1.  
    2. [AsyncMethodBuilder(typeof(NoAllocAsyncVoidMethodBuilder))]
    3. public struct Foo
    4. {
    5.  
    6. }
    7.  
    8. public struct NoAllocAsyncVoidMethodBuilder
    9. {
    10.     private interface IStateMachineBox : IDisposable
    11.     {
    12.         Action MoveNext { get; }
    13.     }
    14.     private class StateMachineBox<TStateMachine> : IStateMachineBox where TStateMachine : IAsyncStateMachine
    15.     {
    16.         static readonly UnityEngine.Pool.ObjectPool<StateMachineBox<TStateMachine>> _pool = new(() => new());
    17.         public static StateMachineBox<TStateMachine> GetOne() => _pool.Get();
    18.         public void Dispose()
    19.         {
    20.             StateMachine = default;
    21.             _pool.Release(this);
    22.         }
    23.  
    24.         public TStateMachine StateMachine { get; set; }
    25.         private void DoMoveNext()
    26.         {
    27.             StateMachine.MoveNext();
    28.         }
    29.         public Action MoveNext { get; }
    30.         public StateMachineBox()
    31.         {
    32.             MoveNext = DoMoveNext;
    33.         }
    34.     }
    35.  
    36.     public Foo Task => default;
    37.  
    38.     IStateMachineBox _stateMachineBox;
    39.  
    40.     IStateMachineBox EnsureStateMachineBox<TStateMachine>() where TStateMachine : IAsyncStateMachine
    41.     {
    42.         if (_stateMachineBox != null)
    43.         {
    44.             return _stateMachineBox;
    45.         }
    46.         _stateMachineBox = StateMachineBox<TStateMachine>.GetOne();
    47.         return _stateMachineBox;
    48.     }
    49.     public static NoAllocAsyncVoidMethodBuilder Create() => default;
    50.  
    51.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
    52.     public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
    53.     {
    54.         var box = EnsureStateMachineBox<TStateMachine>();
    55.         ((StateMachineBox<TStateMachine>)box).StateMachine = stateMachine;
    56.         stateMachine.MoveNext();
    57.     }
    58.  
    59.  
    60.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
    61.     public void SetStateMachine(IAsyncStateMachine stateMachine)
    62.     {
    63.     }
    64.  
    65.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
    66.     public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
    67. where TAwaiter : INotifyCompletion
    68. where TStateMachine : IAsyncStateMachine
    69.     {
    70.         var box = EnsureStateMachineBox<TStateMachine>();
    71.         ((StateMachineBox<TStateMachine>)box).StateMachine = stateMachine;
    72.         awaiter.OnCompleted(box.MoveNext);
    73.     }
    74.  
    75.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
    76.     public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
    77.         where TAwaiter : ICriticalNotifyCompletion
    78.         where TStateMachine : IAsyncStateMachine
    79.     {
    80.         var box = EnsureStateMachineBox<TStateMachine>();
    81.         ((StateMachineBox<TStateMachine>)box).StateMachine = stateMachine;
    82.         awaiter.UnsafeOnCompleted(box.MoveNext);
    83.     }
    84.  
    85.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
    86.     public void SetException(Exception e)
    87.     {
    88.         _stateMachineBox.Dispose();
    89.         _stateMachineBox = null;
    90.     }
    91.  
    92.     [MethodImpl(MethodImplOptions.AggressiveInlining)]
    93.     public void SetResult()
    94.     {
    95.         _stateMachineBox.Dispose();
    96.         _stateMachineBox = null;
    97.     }
    98. }
    99.  
    Unfortunately there is no way in Mono / .Net Standard to specify an async method builder type per method, so I had to introduce this "Foo" structure. But returning async Foo instead of async void does not introduce allocation (provided you don't return it as a result type of your "Update" method, as in that case it gets boxed so that the native caller can check it).

    Also, some interesting though here: Awaitable implements IEnumerator to provide interop with iterator based coroutines... This has a side effect when using it as a Unity behaviour message return type: the iterator based coroutine system will handle it like any custom Enumerator, and will call its MoveNextMethod on each frame until it completes. It should not cause any problem in most cases (the MoveNext implementation just returns IsCompleted), but that is something I totally missed when doing the implementation.
     
  12. SevenPointRed

    SevenPointRed

    Joined:
    Feb 3, 2016
    Posts:
    199
    It's my understanding async void is not ever awaited so wouldn't using it on a unity update mean code in that update could overun into the next frame?
     
    Thaina likes this.
  13. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Thank you, that definitely helps and I can confirm it doesn't alloc and runs with same or a bit better performance than UniTask.

    I don't see a reason why it couldn't be added to the core lib. I'll definitely use it with a name like AwaitFree. But who knows maybe Net core will land in 2023?

    For anyone still wondering what we are talking about, here's how you use Awaiable without allocs (Foo renamed to AwaitFree):
    Code (CSharp):
    1. class BenchAsync : MonoBehaviour
    2. {
    3.     void Awake()
    4.     {
    5.         Work();
    6.     }
    7.  
    8.     async AwaitFree Work()
    9.     {
    10.         await Awaitable.WaitForSecondsAsync(5);
    11.         throw new Exception("test");
    12.     }
    13. }
    To get exceptions in logs I recommend adding LogException:
    Code (CSharp):
    1. public void SetException(Exception e)
    2. {
    3.      Debug.LogException(e);
    4.     _stateMachineBox.Dispose();
    5.     _stateMachineBox = null;
    6. }
     
    SpencerGR, TangerineDev and Thaina like this.
  14. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    There's no point using async Update, it's just a silly way to benchmark it.
    async Task/Awaitable/UniTask Update
    also aren't awaited.
     
    Last edited: Dec 21, 2022
    TangerineDev likes this.
  15. OliverBooth

    OliverBooth

    Joined:
    Jan 25, 2014
    Posts:
    2
    This is not a Unity issue or limitation, this is a Windows limitation because... DOS. You need to explicitly enable long file paths in your registry. Set
    HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled
    to 1.
     
  16. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
    I know, and I have enabled it, and as far as I know every other tool I use has no issues with it (git, Visual Studio, Visual Studio Code, dotnet cli, Node.js, etc.) except for the Unity Editor. In the ticket I have opened the support could reproduce the problem and they said that they are investigating the problem further.
     
  17. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    548
    So this was from a while back, and though I still don't really agree with the black wizardry going on here I came across OpenSesame while I was looking through some UI packages from this guy (check 'm out he's fantastic). Anyway OpenSesame seems to do the whole "call private and internal API" thing: haven't tested it out and I'm not gonna, but thought I would share.
     
  18. TangerineDev

    TangerineDev

    Joined:
    Sep 28, 2020
    Posts:
    122
    Seems like it changes the compiler for a .csproj and I suspect that it won't work... Remember, Unity currently uses it's own compiler right now.

    I wouldn't use it anyways, as it exposes EVERYTHING! That's definitely not secure and definitely not something I would want, especially in a team enviroment!
     
  19. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
    The creator specifically made it unity compatible, it even lets you change the roslyn version
    The creator made a Unity compatible version, it even lets you change the roslyn version https://github.com/mob-sakai/CSharpCompilerSettingsForUnity
     
    TangerineDev likes this.
  20. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    836
    Agreed, though I've always wanted to be able to add an attribute to a class/method like
    [Nosey]
    that would allow it to ignore access modifiers. Not something I'd use very often, but definitely can help avoid unsafe reflection code.
     
    DragonCoder, TangerineDev and cxode like this.
  21. Mindstyler

    Mindstyler

    Joined:
    Aug 29, 2017
    Posts:
    224
    Yes exactly, fully agree. That or some compiler flag.
    Every time i brought it up though people gave me S*** about it. Glad to know i'm not alone in a request like that.
     
  22. HippyJesus

    HippyJesus

    Joined:
    Dec 2, 2020
    Posts:
    8
    @JoshPeterson
    Happy holidays to you and the team!
    Finally got a chance to watch the .net presentation and got even more excited about the changes this will bring with it. The double compile elimination might actually be the thing I'm most excited about from a workflow perspective, just as a sheer time/concentration saver. I tend to start spacing out when the unity bar pops up and it pops up a lot on my sad old laptop (sometimes for minutes at a time just for a simple code change), so it can be a bit of a challenge to stay in the zone when I'm trying to rapidly iterate on some new idea or a troublesome bug.
    Really looking forward to diving into trying awaitable out as well, but haven't made the leap to the alpha yet.
    Here's to hoping that you and the team have had good luck with making all your tests turn green. Any chance you can make me even more hyped and say if its looking good for 2023.2? I seem to remember seeing some mention of it being a possibility many pages ago, but that might be wishful thinking or me just misremembering something.
     
    SpencerGR likes this.
  23. PetrisPeper

    PetrisPeper

    Joined:
    Nov 10, 2017
    Posts:
    62
    I've talked with one of the main devs of NativeAOT about your comment and he'd like you to explain why do you find it non production ready.

    MacOS support has been already merged and will come with .Net 8, Android support is "trivial" to add (I even recall there being successful attempts of it already) and it also has been successfully ported for all major consoles (PlayStation, Xbox and Switch).

    Addtionally, I've seen that the IL2CPP team is already trying to use NativeAOT for the IL2CPP tool.
     
    Nad_B and Huszky like this.
  24. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,049
    I think he didn't mean that the NativeAOT itself are not production ready. But about unity experimental subbranch that replace its own AOT with NativeAOT are not production ready
     
  25. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Most of software isn't production ready for few months after the first "production ready" release. Pre-releases always get too small user base to find all the bugs. Recently that was my experience with Unity 2021.3 LTS and even whole Net.7 that seems less stable than Net.6.

    Anyway for Net7 only these platforms are supported meaning it's definitely not production ready for anything else:
     
  26. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    Thanks! This is exactly the kind of workflow we are excited to improve.
    We're still not ready to give ETAs for releases yet. I will let everyone know for sure when we know that a given part of the .NET Modernization initiative will be ready.
     
  27. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    As @Thaina and @Kamyker mentioned, I'm looking at it from the .NET 7 perspective now. Additionally, we do have more work yet on our side to use NativeAOT integrated with Unity. The good news here is that this is the same work we are doing to use CoreCLR integrated with Unity.

    I did not know that macOS support had already been merged, that is good news! I was not aware that Android and console support was a possibility though. Do you have links to any information about those? I'd love to get more details.

    Yes, we've seen some nice performance improvements vs. using CoreCLR to run IL2CPP (the managed code conversion utility) via NativeAOT on Windows. We're experimenting with that now.

    So in summary, we're watching NativeAOT, and rather excited about the developments here. However I don't expect us to take much action on it until at least after the .NET 8 release, and likely later.
     
  28. PetrisPeper

    PetrisPeper

    Joined:
    Nov 10, 2017
    Posts:
    62
    The issue tracking android is here and here's an example patch for it on top of .Net 7. The big restriction in contrast to Mono is that it doesn't support JNI interop.
    The contact for console ports is available here.
     
    JoshPeterson, TangerineDev and Thaina like this.
  29. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
  30. Huszky

    Huszky

    Joined:
    Mar 25, 2018
    Posts:
    106
    Raise an issue on github, not in this thread
     
  31. TangerineDev

    TangerineDev

    Joined:
    Sep 28, 2020
    Posts:
    122
    hmm you're right, will do
     
  32. PetrisPeper

    PetrisPeper

    Joined:
    Nov 10, 2017
    Posts:
    62
    With .Net having dropped support for Windows 7 and 8.1, will Unity then also drop support for those when moving to it? Or does Unity maybe plan to readd support for those in their fork?
     
  33. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    358
    TangerineDev likes this.
  34. armproducer

    armproducer

    Joined:
    Jan 7, 2023
    Posts:
    1
    Thaks fo sharing! Good news and good plans
     
  35. PoweredOnSoftware

    PoweredOnSoftware

    Joined:
    Apr 10, 2015
    Posts:
    9
    what's the word on more official NuGet support? manually managing lib/*/*.dll files for each package is kind of tedious
     
  36. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    We have no ETA yet, but we are actively working on it now.
     
    OliverBooth, bdovaz and TeodorVecerdi like this.
  37. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,015
    https://github.com/xoofx/UnityNuGet
     
  38. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    548
    nopacc and ledshok like this.
  39. PetrisPeper

    PetrisPeper

    Joined:
    Nov 10, 2017
    Posts:
    62
    Apparently iOS with NativeAOT is also in plans for .Net 8.
     
  40. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    What is the current update on public beta with .net core?
     
  41. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    We don't have an ETA to discuss yet, sorry. We're still heads-down working on this though. We will post here as soon as we feel confident with a release date.
     
    NotaNaN, TeodorVecerdi, cxode and 7 others like this.
  42. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    296
    @JoshPeterson Maybe you could talk a bit about what you're currently working on, what challenges you've faced and how you've resolved them?

    I find this topic very interesting and I'd love to read as much information as possible. The more technical, the better :)
    I've read everything xoofx wrote about .NET Core, GC, his Roslyn experiments and so on.

    Thanks for being so active on the forums!
     
    Thaina, bdovaz and TangerineDev like this.
  43. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    It is probably worth watching the .NET Conf talk I did on behalf of our team, if you've not seen it yet:


    But I think we are due to make a development update here on this thread. I'll plan to do that this week.

    We also have two blog posts with some details scheduled to come out in the next few months, one in early February and one in June (it is difficult to get on the blog post schedule). The focus of these posts will be details about some specific challenge, like the AnimationEvent post we made previously.
     
  44. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,771
    I wanted to give a brief update on our development progress. To recap, our goal with the .NET Modernization Initiative is to bring the best .NET development tools to Unity users. We want to make programming in Unity a joyful experience!

    I won't go into all of the in-progress work we have happening at the moment toward this goal, but I will list a few of the recent milestones we have completed:
    • Our custom marshaling layer now has support for CoreCLR GC-safe marshaling of many types, including most recently strings, arrays, and a few internal Unity base classes.
    • Our not-yet-public CoreCLR scripting backend is now passing many internal tests on both Windows and macOS (macOS is the recent addition here)
    • Support for better async/await support in Unity is shipping in 2023.1 alpha, with excellent feedback and improvements from many on this thread.
    As usual, I don't have an ETA for release of most of these items yet. Once I do know though, I'll share that information here!
     
    SealDev, SpencerGR, NotaNaN and 40 others like this.
  45. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,594
    I am curious about how async/await can be improved.
     
  46. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Compared to UniTask there's some:
    As for something different that both could use maybe alloc free CancellationToken(Source)? I know that C# ones can't be pooled as their state can't be reset to avoid race conditions.


    This looks pretty heavy and really, what's the point?
     
  47. Deleted User

    Deleted User

    Guest

    Sorry if this is a stupid question, but by "alloc free", do you mean something that is natively allocated--unmanaged by the GC--or pre allocated?
     
  48. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,084
    Tbh anything more lightweight than CancellationTokenSource.

    I've looked a bit more and it seems that CancellationTokenSource.TryReset was added in net6 (https://github.com/dotnet/runtime/issues/48492). It can reset not canceled source tokens. Prob could be used for MonoBehaviour.destroyCancellationToken as:
    Code (CSharp):
    1. static Stack<CancellationTokenSource> sourceTokensPool = new();
    2. private CancellationTokenSource m_CancellationTokenSource;
    3. public CancellationToken destroyCancellationToken
    4. {
    5.   get
    6.   {
    7.     if(m_CancellationTokenSource == null)
    8.     {
    9.       if(!sourceTokensPool.TryPop(out m_CancellationTokenSource))
    10.         m_CancellationTokenSource = new CancellationTokenSource();
    11.       OnCancellationTokenCreated();
    12.     }
    13.     return m_CancellationTokenSource.Token;
    14.   }
    15. }
    16.  
    17. public bool TryReturnDestroyCancellationToken()
    18. {
    19.   if(m_CancellationTokenSource.TryReset())
    20.   {
    21.     sourceTokensPool.Push(m_CancellationTokenSource);
    22.     m_CancellationTokenSource = null;
    23.     return true;
    24.   }
    25.   return false;
    26. }
    Then if you care about performance you could try to return token after a task:
    Code (CSharp):
    1. async Awaitable DownloadAndSetImage()
    2. {
    3.   try
    4.   {
    5.     Texture texture = await UnityWebRequestTexture.GetTexture(url, destroyCancellationToken); //when one day UWR has token :)
    6.     TryReturnDestroyCancellationToken();
    7.     myImage.image = texture;
    8.   } catch (OperationCanceledException) {}
    9. }


    Btw, this post explains old method of pooling timeout tokens before net6 with CancelAfter(int.MaxValue) (https://stackoverflow.com/questions/60723430/allocation-free-timeout-on-task)
     
  49. OndrejP

    OndrejP

    Joined:
    Jul 19, 2017
    Posts:
    296
    Whole "cancellation through exceptions" seem "wrong" to me. It seems fine for cancelling tasks based on user requests, but as soon as the cancellation can happen without user input and more frequently, it's problematic for me.

    Some platforms have really slow exceptions and that can severely limit the throughput of such systems. I would much appreciate different cancellation, without involving exceptions. I've seen some approaches used in UniTask, it was not perfect, but it was a good direction IMO. I think we should focus more on that.
     
  50. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Async is really one of the most abused patterns in .Net and I would hate to see it become pervasive in Unity.

    Async was designed to solve for IO. MS coerced it into being it's general api over everything parallel, and that's where async went off the rails generally in .Net. Resulting in the whole 'async all the way' paradigm.

    And to fix the performance issues of async, they introduced ValueTask. Which is broken by design due to it's 'might or milght not block' design. So now you have tons of methods everywhere in .Net libraries that use this, and you have no idea if they block or not. And to make that even worse they put ValueTask on a ton of abstract classes.

    what wikipedia doesn't tell you is that async as a concept really originated back with polling based architectures. I happened to work on some of the early implementations of these. Web scale needed a better way to handle hundreds to thousands of clients waiting on IO. And out of that futures/promises/async was born. It's a pretty good pattern for what it was designed for. The other route was event based popular in languages which only had green threads. Ie nodejs.

    Unity's job system is more aligned with what works well in games. It needs a few more higher level abstractions like ergonomic parallel iterators to really round it out, but overall it fits better.

    The rust ecosystems is a good example of how async is used mostly correctly for what it's actually good at. They start with an excellent set of abstractions that make it easy for the community to use the right tool for the job. Like one of the best thread pools out there. And then another library that uses that to add parallel iterators over all the common collections. And then a separate async library, that wait for it... is almost exclusively used by the community for IO related things.

    There are certainly more people in the game industry that understand a lot of this then in the general .Net population. But there are a ton of people using Unity especially on the mobile side that really have no clue. I think it's really up to Unity to be a bit opinionated and push these people in the right direction. Nobody is doing them a service by making it easy for them to shoot themselves in the foot.