/C-Sharp-Cancellable-Promise

Promises library for C# for management of asynchronous operations with cancellation support.

Primary LanguageC#MIT LicenseMIT

C-Sharp-Cancellable-Promise unity

stability-stable License: MIT Maintenance

That is a fork of RSG.Promise with an addition of promises cancellation.

Promises cancellation

Promises in most libraries (as of ECMAScript 6) are uncancellable by default. There are discussions about how to cancel promises in a right way going. There is also a wide variety of approaches & libs in different langs that provide cancellation.

Original repository doesn't support it either. This fork adds Cancellation support to it.

It is pretty straightforward: Cancel() cancels all the connected chain of Then & other calls (value & non-value promises; All & Race - all supports cancellation).

Promises now know about parents & children of each other. That is used to perform total cancellation whether you call Cancel like that:

var promise = new Promise();
promise.Then(...).Then(...);
promise.Cancel();

or like that

var promise = new Promise();
promise.Then(...);
promise.Then(...).Then(...).CancelWith(provider);

The only callbacks that are called upon Promise cancellation are:

public void Finally(Action onComplete);
public void OnCancel(Action onCancel);

See examples in Example6.cs and tests in PromiseCancelTests.cs.

Breaking changes

  • Finally() method changed to not return anything.
public void Finally(Action onComplete);

So you won't be able to call something like:

var promise = new Promise();
promise.Then(...).Finally(...).Then(...).CancelWith(provider);

which seems to be pretty ambigious.

  • Catch() rejects promise but there is CatchAsResolved() for backward compatibility.
  • Generic promise now has a covariant modifier
  • Dropped support of Catch(Func<Exception, TPromised>) to support covariant modifier
  • Code style fixed to be more .NET-style

Cancellation utilities

For an additional code see branch dispose_service where you can find DisposeService project with tools to deal with cancellation and objects disposal in a neat way. See examples:

public class ExampleMonoBehaviour : DisposableMonoBehaviour // plain MonoBehaviour will also be fine. CancelWith can deal with it too
{
    private void Start()
    {
        // here we indicate that this Promise must be cancelled with the end of lifecycle of this object.
        DoLongAction().CancelWith(this);
    }

    private IPromise DoLongAction()
    {
        // something long enough which may finish by the time the Example gameObject will be destroyed.
    }
}

public class ExampleState : DisposableFSMState // (custom class which inherits from IDisposeProvider)
{
    protected override void OnEnter()
    {
        base.OnEnter();
        // here we indicate that this Promise must be cancelled with the end of lifecycle of this state.
        DoLongAction().CancelWith(this);
    }

    private IPromise DoLongAction()
    {
        // something long enough which may finish by the time the ExampleState will be finished.
    }
}

Getting it in your project

The simplest way would be to copy all sources from /src/Promises folder to your Unity project.

Otherwise, see the RSG.Promise project for the all code you may need.

PS: Promises or Observables

The original documentation can be found here. There you can get familiar with the Promise concept in more details.

An explanation of Promise concept can also be found in this thread.

Shortly:

  • use Promises when you have a single async operation of which you want to process the result.
  • use Observables when there is a stream (of data) over time which you need to be handled.