Search Unity

Asynchronous operations (promises) for Unity (FREE)

Discussion in 'Assets and Asset Store' started by Arvtesh, Mar 21, 2018.

  1. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hello Everyone!

    I'd like to announce that Asynchronous operations for Unity is now available on the Asset Store.

    What is Asynchronous operations for Unity?
    It is a set of C# classes and interfaces that extend Unity asynchronous operations (ex. AsyncOperation, Coroutine) and can be used very much like .NET Tasks. The library at its core defines a container (AsyncResult) for state and result value of an asynchronous operation (aka promise or future). In many aspects it mimics Task (for example, it supports continuations and capturing of synchronization context).

    In short it is a lightweight and .NET 3.5-compatible alternative to .NET tasks designed with the following goals in mind:
    • Open source. All library sources are available on Github.
    • Extensible. Users can create own asynchronous operations.
    • Thread-safe. Library classes can be safely accessed from background threads (unless explicitly states otherwise).
    • Task-like interface and behaviour. In most cases library classes can be used just like corresponding TPL entities.
    • Unity compatibility. This includes possibilty to yield any operation in a Unity coroutine and .NET 3.5 compilance.
    • Minimum allocations.
    Why should I use it?
    Well, the main reason for using it is because neither Unity nor .NET 3.5 provide an extensible asynchronous operation implementation. The only option is using Unity coroutines and those are quite limited:
    • Coroutines cannot return values.
    • Coroutines have no way to signal an error.
    • Running a coroutine requires a MonoBehaviour instance.
    • The only way to know if a coroutine has completed.
    With Unity 2017 and .NET 4.6 support tasks are great example of an extendable asynchronous operation. Still one should consider using this package is one of the following applies:
    • .NET 3.5 compatibility is required.
    • Promise-like continuations required.
    • Memory usage is a concern (Tasks tend to do quite many allocations).
    • An extendable IAsyncResult implementation is needed.
    List of features:
    • Open source.
    • .NET 3.5/.NET 4.6 support.
    • Task-like interface familiar to any .NET developer.
    • No MonoBehaviour is needed to run the operations.
    • Continuations support.
    • Promise-like continuations.
    • All operations are yieldable.
    • async/await operators are supported for .NET 4.6.
    • All classes are thread safe.
    • Extensions for Unity standard asynchronous operations that convert them to library asynchronous operations are provided.
    • Full source code is available on Github.
    Useful links:
    P.S. I would be pleased if my work would help someone. Any feedback is much appreciated.
     
    Last edited: Apr 26, 2018
    SugoiDev, one_one, voyagelms and 3 others like this.
  2. Arkade

    Arkade

    Joined:
    Oct 11, 2012
    Posts:
    655
    This sounds superb. I'm on mobile atm so forgive of this is in docs but since it's likely a FAQ (at least for mobile devs):

    Could you write more about the memory implications? E.g. are allocations only at creation (vs. every yield, frame, etc) How much? Can one mitigate with certain coding patterns? Any plans to improve?

    Thanks!
     
  3. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey! First of all thank you for your interest in the library. It is still work in progress and any feedback or suggestions are very helpful.

    Now to the questions. The allocations (not counting operation creation):
    1. Yielding operation in a coroutine does not allocate any additional memory.
    2. There are no allocations per frame.
    3. AggregateException instance is allocated when an operation transitions to either failed or canceled state (this matches Task behaviour).
    4. Adding completion callbacks might allocate additional memory depending on whether you choose to capture synchronization context or not and the existing callbacks count. When adding first callback without capturing the context no allocations are needed (and that is quite common case).
    5. Using async/await always does at least one allocation (because the implementation has to capture current synchronization context).
    6. Accessing AsyncWaitHandle lazily instantiates the handle object (the same applies for Wait/Join extensions). But that is quite rare use-case.
    For more detailed description of library usage please see the Github README.

    As I mentioned earlier the library is still in development. I use it in several my projects and make improvements based on my personal experience and feedback from my colleagues.

    Hope that answers your questions.

    P.S. The asset store package assemblies target .NET 3.5 so there is no code for async/await support and Task conversions. If it is needed you may download assemblies that traget .NET 4.6 from Github releases.
     
  4. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    v0.8.2 released!

    Notable changes:
    1. Added new AsyncResult constructors.
    2. Added new overloads to AsyncResult.FromResult, AsyncResult.FromException and AsyncResult.FromCanceled.
    3. Optimized ToTask extension method for cases when target operation is completed.
    4. Marked assembly classes as CSL-compilant.
    5. ToTask extension methods now throw inner exception (instead of AggregateException) in case of an error.
    6. Fixed AsyncResult.Delay arguments validation.
     
  5. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    v0.9.0 released!

    Main features added are:
    • Promise-like continuations (Then/Catch/Finally).
    • Operation cancellation support.
    • Frame updates service.
    • Many other improvements and bugfixes (see full CHANGELOG).
     
  6. envy82

    envy82

    Joined:
    Oct 18, 2016
    Posts:
    9
    That's quite useful asset! I really enjoy using it. So sad the Asset Store package does not support .NET 4.6 / netstandard 2.0 features.
     
  7. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Unfortunately that's a Unity limitation: DLLs can't be mapped to .NET framework versions currently. Please use Github releases to get the DLLs compiled for .NET 4.6/nestandard 2.0.
     
  8. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    v0.9.2 released!

    Notable changes:
    Added:
    • Added pull-based progress support (IAsyncOperation.Progress).
    • Added new methods to IAsyncUpdateSource.
    • Added AsyncUpdateSource class as default IAsyncUpdateSource implementation.
    • IAsyncOperation<T> now inherits IObservable<T>.
    Changed:
    • Renamed (Try)AddCompletionCallback/RemoveCompletionCallback methods to (Try)AddContinuation/RemoveContinuation.
    • Changed IAsyncOperation.Exception type to Exception.
    • Changed IAsyncOperationEvents.Completed type to AsyncCompletedEventHandler.
    Removed:
    • Removed ToObservable extension of IAsyncOperation.
     
  9. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey, v0.9.3 released!

    This release introduces push-based progress notifications for all operations, heavy optimizations of memory management for common use-cases and many minor improvements/bugfixes.

    Notable changes:
    Added
    - Added push-based progress reporting support.
    - Added `AsyncResult.Delay(float)` overloads.
    - Added `AsyncCreationOptions.SuppressCancellation` option.
    - Added update sources for `LateUpdate`, `FixedUpdate` and end-of-frame updates.
    - Added `SynchronizationContext` for the main thread (if not set by Unity).
    - Added methods `AsyncUtility.PostToMainThread`, `AsyncUtility.SendToMainThread` as `AsyncUtility.InvokeOnMainThread`.
    - Added new `FromAction` overloads.

    Changed
    - Significantly reduced number of memory allocations when adding continuations/progress callbacks.
    - Changed signature of the `IAsyncContinuation.Invoke` method.
    - Changed `AsyncResult.OnCancel` implementation to do nothing (previously it threw `NotSupportedException`).

    Fixed
    - Fixed exception when removing listeners while in `AsyncUpdateSource.OnError` / `AsyncUpdateSource.OnCompleted` / `AsyncUpdateSource.Dispose`.
    - Fixed `AsyncResult.MoveNext` to always return `true` while the operation is not completed.
    - Fixed `AsyncResult` construction code not working as intended when `AsyncCreationOptions` are specified.

    Removed
    - Removed `AsyncOperationCallback` delegate type.
     
  10. Firlefanz73

    Firlefanz73

    Joined:
    Apr 2, 2015
    Posts:
    1,316
    Sounds interesting.
    Do these tasks work with parallel multithreading on multiple cpu (for example if I use them for object calculating and spawning like chunks for landscape like in minecraft) or is it just on main cpu?

    Thanks :)
     
  11. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    You can use the asynchronous operations from any thread. You can also access them from multiple threads at the same time (if that's what you mean).

    That said, unlike .NET tasks asynchronous operations do not create new threads, they just provide a convenient way of tracking actual execution. The TaskCompletionSource in .NET and JS promises are the closest analogs.
     
  12. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hi everyone, v0.9.4 released!

    Notable changes:
    Added
    • Added assembly definition file for Unity 2017.3+.
    • Added AsyncResult.FaultedOperation helper.
    • Added AsyncUtility.IsMainThread method.
    • Added AsyncUtility.GetAssetBundle, AsyncUtility.GetTexture, AsyncUtility.AudioClip and AsyncUtility.GetMovieTexture helper methods.
    • Added AssetBundleCreateRequest wrapper operation.
    • Added ThrowIfNonSuccess extension for IAsyncOperation.
    • Added ToEnum extension for IAsyncResult that converts an asynchronous operation (Task, AsyncResult etc) to enumerator.
    • Added IAsyncSchedulable interface - an abstraction of a schedulable entity.
    • Added AsyncLazy helper for initialization operations.
    Fixed
    • Fixed compile warnings for some older Unity versions.
    • Fixed error handling for Unity operation wrappers.
     
  13. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey everyone! A new version is released: 0.9.5.

    Release notes:
    Added:
    • Added IAsyncOperation.Id property for easy operation identification.
    • Added AsyncUtility.GetText and AsyncUtility.GetBytes helpers.
    • Added ToTask extensions for AsyncOperation/UnityWebRequest/WWW.
    • AsyncResult now implements IAsyncContinuation to enable easy operation chaining.

    Fixed:
    • Fixed compile warnings for Unity 2018.2.

    Removed:
    • Removed ToAsyncXxx extension methods for WWW and UnityWebRequest.
    • Removed MovieTexture related methods for Unity 2018.2 (the class is deprecated now).
    • Removed IAsyncSchedulable interface (it was just another form of IAsyncContinuation).
     
  14. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey! The new version is here: v0.9.7. It brings massive improvements both feature and performace wise.

    Release notes:
    Added:
    • Added convenience overloads for SetException-like methods accepting as error message string.
    • Added allocation optimizations for single-threaded applications (particularly for Unity3d). See AsyncResult.DefaultSynchronizationContext for more info.
    • Added new overloads for ConfigureAwait extensions accepting continuation options instead of boolean flag.
    • Added SynchronizationContext extension methods for Send/Post accepting Action as the delegate.
    • Added AsyncResult.Yield static method (workd exactly as Task.Yield).
    • Added AsyncUtility.AddFrameCallback helper for scheduling delegates for MonoBehaviour update loop.
    • Signed the assembly with a strong name.
    • Added Play/Wait extension methods for Animation and Animator.
    • Added AsyncResult.IsStarted helper property.
    Fixed:
    • Fixed error handling in AsyncOperationResult.
    Changed:
    • Changed AsyncResult constructors argument order to avoid ambiguity in some cases.
    • Moved the package content to Plugins folder and remove assembly definition file.
    • Moved web request related helpers from AsyncUtility to AsyncWww class.
    • Changed AsyncUtility.SendToMainThread, AsyncUtility.PostToMainThread and AsyncUtility.InvokeOnMainThread implementation to use ConcurrentQueue for net46+ to avoid unnesesary locks.
    • Moved several of IAsyncOperationEvents methods to the interface extensions.
    Removed:
    • Removed Asset Store samples.
    • Dropped Unity 5.0 support (the minimum version supported is now 5.4).
    • Dropped WWW support for Unity 2018.3+ (it has been deprecated in Unity).
    • Removed IAsyncOperationEvents.TryAddCompletionCallback and IAsyncOperationEvents.TryAddProgressCallback methods. These methods are not needed in 99% of cases and may lead to logic errors in multi-threaded environment.
    If you enjoy using the library - please, rate and review it on the Asset Store!
     
  15. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hello everyone. The pre-release version of UnityFx.Async is out!

    Notable changes:
    Added
    • AsyncResult is now Task-like type and can be used as async method result value (requires C# 7.2).
    • Added new AsyncResult.FromAction overloads.
    • Added new SynchronizationContext extension methods (PostAsync, InvokeAsync etc).
    • Added extension methods for Socket, WebRequest, Stream BCL classes.
    Changed
    • Moved BCL extension methods to namespace UnityFx.Async.Extensions (previously they were in namespace UnityFx.Async).
    Fixed
    • Fixed AsyncResult completion callbacks to be called event if OnCompleted throws.
    • Fixed exception not been set for AsyncResult.FaultedOperation and AsyncResult.CanceledOperation.
    • Disabled MovieTexture helpers for iOS/Android (as it is not supported on mobiles).
     
  16. voyagelms

    voyagelms

    Joined:
    Jul 12, 2017
    Posts:
    7
    Hey @Arvtesh, would it be possible if you could produce a contrived example of how the ProgressChanged handler for AsyncCompletedSource works using UnityWebRequest?

    Using the example in your repo, I've modified the example to demonstrate my issue.

    Code (CSharp):
    1. public IAsyncOperation<SomeContainer> DownloadDataAsync(string url)
    2. {
    3.     var result = new AsyncCompletionSource<SomeContainer>();
    4.     StartCoroutine(DownloadDataInternal(result, url));
    5.     result.ProgressChanged += ( sender, args ) => {
    6.       Debug.Log(args.ProgressPercentage);
    7.     }
    8.     return result;
    9. }
    10.  
    11. private IEnumerator DownloadDataInternal(IAsyncCompletionSource<SomeContainer> op, string url)
    12. {
    13.     var www = UnityWebRequest.Get(url);
    14.     var result = www.SendWebRequest();
    15.  
    16.     while (!result.isDone) {
    17.       op.SetProgress<SomeContainer>(result.progress);
    18.       yield return null;
    19.     }
    20.  
    21.     if (www.isNetworkError || www.isHttpError)
    22.     {
    23.         op.SetException(new Exception(www.error));
    24.     }
    25.     else
    26.     {
    27.         SomeContainer result = processRawData(www.downloadHandler.data);
    28.         op.SetResult(result);
    29.     }
    30. }
    Instead of a string, I'm downloading a byte[] and on completion processing the resulting byte[] into an arbitrary class container, where the data is written to the local file system and its path saved within the container. The result from implementing the ProgressChange is the following error.

    Code (CSharp):
    1. InvalidOperationException: The operation state cannot be changed. Most likely the operation is already completed.
    I feel like I'm missing a critical detail, but after spending a couple of days pouring through the repo and the Unity docs, I've opted to ask the creator. xD

    Any help, advice, or resources would be greatly appreciated!!
     
  17. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey @voyagelms! It looks like you have to pass AsyncOperationStatus.Running to the AsyncCompletionSource constructor because current implementatin only allows progress changes when the op is running. That's not an obvious thing at all actually. I'll have to either clarify it in docs or change it.

    Thank you for using UnityFx.Async. Hope this helps!
     
    voyagelms likes this.
  18. voyagelms

    voyagelms

    Joined:
    Jul 12, 2017
    Posts:
    7
    @Arvtesh, that did the trick!!!

    Thanks for the help!!

    Would you mind if I submit a PR to your repo with the clarification / addition?

    There are two things I'd like to contribute.
    - Elaborate the ProgressReporting section with the addition of AsyncOperationStatus.

    With that said, is that an acceptable supplement to the documentation? I'm not sure what changes you had planned on the roadmap for the library, but I definitely want to avoid adding any misleading, incorrect, or ambiguous documentation.

    - Modifying the above example to be a working example of ProgressReporting to be included in /src/UnityFx.Async.Examples/Examples.

    I'm a lot more wary and hesitant on this mainly because I'm not sure if that implementation is the best way to implement ProgressReporting. ( Mainly because of the coroutine. )

    What improvements do you think can be made to that example? I was analyzing this example within the code base, and I kind of made the assumption that coroutines are not essential to implementing ProgressReporting.

    Lastly, you're welcome!!!
    But really, thank you for making and open-sourcing for free such a top notch, well tested, documented, just all around amazing library!!
    By far one of the most beautiful open source libraries I've ever encountered.

    Thank you, thank you, thank you!!!
    I'll be recommending it among my classmates and to the course instructor, for sure!!
     
  19. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    @voyagelms, I'm going to change the AsyncCompletionSource.SetProgress implementation to make your former test case (as well as the library examples) work as they are. Current implementation is quite unobvious (call it a bug). I'll push the fix to develop a bit later.

    P.S. So no need for PR this time, thank you.
     
    voyagelms likes this.
  20. voyagelms

    voyagelms

    Joined:
    Jul 12, 2017
    Posts:
    7
    No problem!! Thanks for letting me know @Arvtesh!!
     
  21. jdnichollsc

    jdnichollsc

    Joined:
    Sep 23, 2017
    Posts:
    9
  22. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey! Thanks for your interest in the library! I answered your question in the Github thread you linked.
     
  23. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hey! Finally release version of UnityFx.Async is out!

    Notable changes:
    Added
    • Added more comments throughout the code.
    • Added Unity 2018.3 support (esp. support all target .NET frameworks in a single Asset Store package).
    • Added await support to YieldInstruction Unity class.
    • Added coroutine helpers (AsyncUtility.FromCoroutine).
    • Added helpers for loading assets from an AssetBundle.
    • Added AsyncUtility.FrameTime await helper.
    Changed
    • Added DebuggerHidden attribute to some properties/methods to make stack traces a bit more friendly.
    • Renamed AsyncContinuationContext to AsyncCallbackOptions.
    • Renamed web request helper methods (added `Async` postfix to their names).
    • Moved Unity extension methods to UnityFx.Async.Extensions namespace (previously they were in namespace UnityFx.Async).
    Fixed
    • Fixed web requests `null` result in cases when downloaded file failed to open.
    • Fixed AsyncUtility.AddCompletionCallback exception when adding new callbacks from another callback.
    • Fixed AsyncUpdateSource implementation to allow adding listeners from a callback.
    • Fixed AsyncCompletionSource.SetProgress implementation to allow setting progress when the operation is not started.
    Removed
    • Removed many specialized IAsyncOperationCallbacks methods to make the interface as minimalistic as possible (new extension methods are added to compensate).
    • Removed (Try)SetExceptions methods/extensions and FromExceptions helpers.
    • Removed extension methods of the `Animation` class.
    • Removed WaitAsync extension methods of the `Animator` class.
    • Dropped MovieTexture support.
     
    shadowlord1 likes this.
  24. shadowlord1

    shadowlord1

    Joined:
    Aug 15, 2014
    Posts:
    32
    Hello guys!
    Does it works with IL2CPP?
     
  25. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hi! Yes the library should work with IL2CPP on all platforms.
     
    shadowlord1 likes this.
  26. one_one

    one_one

    Joined:
    May 20, 2013
    Posts:
    621
    Ohh, very interesting! Not sure why I missed that when I was looking for a C# promises implementation.
     
    shadowlord1 likes this.
  27. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Give it a try!
     
  28. one_one

    one_one

    Joined:
    May 20, 2013
    Posts:
    621
    I'm tempted. After having recently switched to .NET 4.6, though, I'm considering just using tasks. I need asynchronous behaviour in central pieces of code and it just 'feels' safer to use built-in language features there. I'm not too attached to having a Promise syntax and while fewer allocations are always nice, it's not crucial in that context. Then again, I'd probably need another third-party project to make that run nicely. Hmm.
     
    Last edited: Mar 8, 2019
  29. shadowlord1

    shadowlord1

    Joined:
    Aug 15, 2014
    Posts:
    32
    By reading the NET.Tasks documentation, it has an example of a task running synchronously (T4).
    Since T4 is synchronous it runs on the main application Thread... The remaining tasks execute asynchronously typically on one or more thread pool threads.
    How does this package work in Unity? Does it has the same "Thread pool" concept where it spawns new threads if necessary or it keeps all tasks in the same thread as Unity? And just as a coroutine, it keeps "switching" from task 1 to task 2, to make it seems parallel? (Since you said Asynchronous operations don't create threads, so they can't be parallel, it means they'll block the main thread if a given async operation is time-consuming?) I'm sorry if my question have already being answered, I didn't find it on the forum.

    Thank you!
     
  30. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    I think the main thing here is understanding that promise != thread. Using promises does not imply creating any asynchronous operations (threads) at all.

    Promises are a design pattern to structure asynchronous code and smooth over the complexities of running sequences of (dependent) asynchronous operations. In other words promises are just wrappers over operations of any kind.

    To illustrate consider the following sample:
    We need promise to observe a message box lifetime. A promise is started when the message box is presented and it is completed when the message box is dismissed. The promise implementation do not have to create threads, it just subscribes to system events for the message box.

    .NET Task represents consumer side of a promise while TaskCompletionSource is its producer side. To implement the above sample with TPL one would create a TaskCompletionSource instance and call TaskCompletionSource.SetResult() when the message box is closed, TaskCompletionSource.Task would represent a lifetime of the message box.

    UnityFx.Async implements a generic promise (AsyncResult) that can be used to wrap any kind of operation (including asynchronous operations that are executed on other threads). All library promises can be yielded in Unity coroutines, awaited in async methods, they define completion/progress notifications and provide cancellation mechanisms. The library includes implementations of promise wrappers for several widely used operations like timers, delays, AsyncOperation, WWW etc. It also defines extensions for Unity asynchronous operations to make them awaitable and promise conversions.

    There is an excellent article that is a must-read for anyone interested in promises.

    Hope this helps. Please ask more questions if I failed in making myself clear enough!
     
    one_one likes this.
  31. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    The library provides a promise wrapper for Unity's AsyncOperation through ToAsync() extension method. So you can do something like:
    Code (CSharp):
    1. using UnityEngine.SceneManagement;
    2. using UnityFx.Async.Extensions;
    3.  
    4. var promise = SceneManager.LoadSceneAsync("myScene").ToAsync();
    5.  
     
    one_one likes this.
  32. shadowlord1

    shadowlord1

    Joined:
    Aug 15, 2014
    Posts:
    32
    Thank you very much for the didactic answer Arvtesh! Keep it up the good work!
     
    envy82 likes this.
  33. greay

    greay

    Joined:
    Mar 23, 2011
    Posts:
    88
    I'm having some trouble with the FrameUpdate stuff. I have a method that, for various reasons, I'm converting from using an IEnumerator to the newer Tasks. This is my (pseudo)code:

    Code (CSharp):
    1. public async Task<Texture2D> TakeShot( )
    2. {
    3.     // do some setup
    4.     await AsyncUtility.FrameUpdate(UnityFx.Async.FrameTiming.EndOfFrame);
    5.     // generate screenshot
    6.     return myTexture;
    7. }
    The code sets up the scene & lighting to take a screenshot. Waits a frame, generates the screenshot, then returns it. At least, that's what it's meant to do. While the older coroutine method worked as intended, the current code hits the await and then stops. It never continues.

    Is there something I'm missing?
     
  34. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hi @greay, thank you for reporting the issue. It appears there is a bug that prevents the EOF callback from been scheduled. I'm going to make a patch release a bit later.

    P.S. If you need just Task-related extensions of Unity API, you can give a try to UnityFx.Tasks. It is not published to the Asset Store yet, but it should be stable enough.
     
  35. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hello everyone! UnityFx.Async v1.0.2 is released!

    Notable changes:
    Changed
    • Deprecated all `Task`-related extension methods. They are considered out of the library scope.

    Fixed
    • Fixed `AsyncUtility.FrameUpdate` not scheduling callbacks.
     
  36. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    Will definitely take it for a spin when I get an opportunity!

    Few questions:
    1) Is it possible to execute async operations in editor mode?
    2) Is it possible to run unity-relared methods such as AssetDatabase.Load()
    3) Does it work with custom editor UI? As in, can I use this to unblock the UI inout while peocesproc async operations? I know this is possible in WPF or WinForms, but using async alone would make Unity freak out.

    Apologies if this has been answered beforehand.
     
    Last edited: Jun 3, 2019
  37. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    Hi! Thank you for the interest! I’m sorry for the delay with reply, busy at the office. Now to your questions:
    1. I never tested the library in edit mode. I think coroutines-related stuff and frame callbacks might not work. But the library core should still be usable because it does not depend on Unity.
    2. The mentioned method blocks the caller thread as I understand, and there is no async version of it. So I don’t think the library can be of any help with it.
    3. There is no specific code fo editor ui and the library is not tested in editor. I’m not sure I understand your concern here. Could you explain a bit more?
     
  38. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    Hello!

    I think I would make more sense if I explain my problem in full instead :p

    Let's say I have a custom editor. It's job is simple: get the list of all files from a specific directory and render themthe the editor when I click a button.

    If I click a button, it would begin looking up all files in a directory recursively. This operation is long.

    What happens in editor UI, because operation is synchronous, is that I can't interact with the UI (e.g. pressing buttons, moving windows etc.) while that operation is being executed.

    A practical solution to this problem is to use async/await. It runs a complex operation alongside UI thread, which means users can interact with it. WPF and WinForms work perfectly with async await.

    When it comes to Unity though, I encounter 2 problems:
    First problem, as you already know, you can't run Unity specific methods outside the main thread. Second problem is that editor UI doesn't cope well with contents being updated. It has to do with repaint events but I would still need to investigate that in more depth.
     
  39. envy82

    envy82

    Joined:
    Oct 18, 2016
    Posts:
    9
    @elmar1028 It seems Tasks is what you need. According to this thread latest Unity versions should provide built-in SynchronizationContext for the editor main thread, which in turn should make async/await usable.
     
    elmar1028 likes this.
  40. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,359
    I am surprised I haven't come across this thread until now. Thanks!
     
  41. Arvtesh

    Arvtesh

    Joined:
    Aug 16, 2014
    Posts:
    94
    As stated above the first problem should be solved with async/await. So if you don’t have to use legacy net35 framework, this is probably what you need. I’m not sure what to do with the second one though.
     
  42. skullthug

    skullthug

    Joined:
    Oct 16, 2011
    Posts:
    202
    Hello, I was curious if this package is still being maintained? I noticed the last update was 1.0.2 in 2019.
    I'm encountering some issues with trying to use it with Universal Windows Platform in Unity 2021 (in the year 2023)

    I receive the following errors in the Editor after opening the project and switching the build to UWP. (For context we updated to Unity 2021 for iOS/Android builds successfully already)

     
  43. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,859
    If you're looking for a current day async package for Unity, UniTask is the no-brainer option: https://github.com/Cysharp/UniTask
     
  44. skullthug

    skullthug

    Joined:
    Oct 16, 2011
    Posts:
    202
    Thanks for the useful tip. It looks like I'll probably have to keep that in my pocket for a future update when I have more time to jump into that.

    For now, for anyone else Googling who ran into this specific UnityFx error though, I managed to fix the error by downloading the 1.1.0 release that was only published on the UnityFx Github (it's not published on the Asset store).
     
    Last edited: Nov 9, 2023