Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
C

C-Sharp-Promise

> 编程语言
Open source

Promises library for C# for management of asynchronous operations.

1.2K stars0 likes0 views
WebsiteGitHub

About

Promises library for C# for management of asynchronous operations.

C-Sharp-Promise

Promises library for C# for management of asynchronous operations.

Inspired by JavaScript promises, but slightly different.

Used by Real Serious Games for building serious games and simulations on Unity3d.

If you are interested in using promises for game development and Unity please see this article.

Recent Updates

  • v3.0 (15 Feburary 2018)
    • Finally has been modified to work in a way consistent to Promise.prototype.finally() in JavaScript.
    • Added support for reporting progress in a promise.
    • Signed assembly with a strong name.
    • Errors throw custom exception types rather than generic ones.
    • Modified some overloads of Then that didn't make sense.
  • v2.0 (4 December 2017)
    • Then functions chained after a Catch are now run after the exception is handled rather than being terminated
    • Catch can return a value which will be passed into the next Then
    • The onResolved callback of Then can now also return a value which is passed to the next promise in the same way
    • Added elapsedUpdates property to the TimeData struct used by PromiseTimer
  • v1.3 (28 October 2017)
    • Added Cancel method to PromiseTimer
    • Implemented an overload of Promise.All that works on Tuples of multiple types
    • Implemented Finally method
    • Removed dependency on RSG.Toolkit
  • v1.2 (8 March 2015)
    • Transform function has been renamed to Then (another overload of Then).

Projects using this library

  • RestClient for Unity

Contents

Table of Contents generated with DocToc

  • Understanding Promises
  • Promises/A+ Spec
  • Getting the DLL
  • Getting the Code
  • Creating a Promise for an Async Operation
  • Creating a Promise, Alternate Method
  • Waiting for an Async Operation to Complete
  • Chaining Async Operations
  • Transforming the Results
  • Error Handling
  • Unhandled Errors
  • Progress reporting
  • Promises that are already Resolved/Rejected
  • Interfaces
  • Combining Multiple Async Operations
  • Chaining Multiple Async Operations
  • Racing Asynchronous Operations
  • Chaining Synchronous Actions that have no Result
  • Promises that have no Results (a non-value promise)
  • Convert a value promise to a non-value promise
  • Running a Sequence of Operations
  • Combining Parallel and Sequential Operations
  • Weighted averaging of progress on multiple promises
  • PromiseTimer class
    • PromiseTimer.WaitFor
    • PromiseTimer.WaitUntil
    • PromiseTimer.WaitWhile
    • TimeData struct
  • Examples

Understanding Promises

To learn about promises:

  • Promises on Wikpedia
  • Good overview
  • Mozilla

Promises/A+ Spec

This promise library conforms to the Promises/A+ Spec (at least, as far as is possible with C#):

Getting the DLL

The DLL can be installed via nuget. Use the Package Manager UI or console in Visual Studio or use nuget from the command line.

See here for instructions on installing a package via nuget: http://docs.nuget.org/docs/start-here/using-the-package-manager-console

The package to search for is RSG.Promise.

Getting the Code

You can get the code by cloning the github repository. You can do this in a UI like SourceTree or you can do it from the command line as follows:

bash
git clone https://github.com/Real-Serious-Games/C-Sharp-Promise.git

Alternately, to contribute please fork the project in github.

Creating a Promise for an Async Operation

Reference the DLL and import the namespace:

cs
using RSG;

Create a promise before you start the async operation:

cs
var promise = new Promise();

The type of the promise should reflect the result of the async op.

Then initiate your async operation and return the promise to the caller.

Upon completion of the async op the promise is resolved:

cs
promise.Resolve(myValue);

The promise is rejected on error/exception:

cs
promise.Reject(myException);

To see it in context, here is an example function that downloads text from a URL. The promise is resolved when the download completes. If there is an error during download, say unresolved domain name, then the promise is rejected:

…

Creating a Promise, Alternate Method

There is another way to create a promise that replicates the JavaScript convention of passing a resolver function into the constructor. The resolver function is passed functions that resolve or reject the promise. This allows you to express the previous example like this:

…

Waiting for an Async Operation to Complete

The simplest usage is to register a completion handler to be invoked on completion of the async op:

cs
Download("http://www.google.com")
    .Then(html =>
        Console.WriteLine(html)
    );

This snippet downloads the front page from Google and prints it to the console.

For all but the most trivial applications you will also want to register an error hander:

cs
Download("http://www.google.com")
    .Then(html =>
        Console.WriteLine(html)
    )
    .Catch(exception =>
        Console.WriteLine("An exception occured while downloading!")
    );

The chain of processing for a promise ends as soon as an error/exception occurs. In this case when an error occurs the Catch handler would be called, but not the Done handler. If there is no error, then only Done is called.

Chaining Async Operations

Multiple async operations can be chained one after the other using Then:

cs
Download("http://www.google.com")
    .Then(html =>
        return Download(ExtractFirstLink(html)) // Extract the first link and download it.
    )
    .Then(firstLinkHtml =>
        Console.WriteLine(firstLinkHtml)
    )
    .Catch(exception =>
        Console.WriteLine("An exception occured while downloading!")
    );

Here we are chaining another download onto the end of the first download. The first link in the html is extracted and we then download that. Then expects the return value to be another promise. The chained promise can have a different result type.

Transforming the Results

Sometimes you will want to simply transform or modify the resulting value without chaining another async operation.

cs
Download("http://www.google.com")
    .Then(html =>
        return ExtractAllLinks(html))   // Extract all links and return an array of strings.
    )
    .Then(links =>                      // The input here is an array of strings.
        foreach (var link in links)
        {
            Console.WriteLine(link);
        }
    );

As is demonstrated the type of the value can also be changed during transformation. In the previous snippet a Promise is transformed to a Promise.

Error Handling

An error raised in a callback aborts the function and all subsequent callbacks in the chain:

cs
promise.Then(v => Something())   //  SomethingElse())
    .Then(v => AnotherThing())
    .Catch(e => HandleError(e))  //  Something())
    .Then(v => SomethingElse())
    .Then(v => AnotherThing())
    .Done();    //  Log.Info("Current progress is " + (100f * progress) + "%"));

Listening for progress on a Then call:

cs
var promiseA = new Promise();
var promiseB = new Promise();
promise
    .Then(() => promiseB, null, (progress) => Log.Info("promiseA made progress: " + progress))
    .Progress(progress => Log.Info("promiseB made progress: " + progress));

In order to report progress for a promise, you need to call the ReportProgress method:

cs
var promise = new Promise();
promise.ReportProgress(0.5f); // Report a 50% completion

Promises that are already Resolved/Rejected

For convenience or testing you will at some point need to create a promise that starts out in the resolved or rejected state. This is easy to achieve using Resolved and Rejected functions:

cs
var resolvedPromise = Promise.Resolved("some result");

var rejectedPromise = Promise.Rejected(someException);

Interfaces

The class Promise implements the following interfaces:

  • IPromise Interface to await promise resolution.
  • IPendingPromise Interface that can resolve or reject the promise.

Combining Multiple Async Operations

The All function combines multiple async operations to run in parallel. It converts a collection of promises or a variable length parameter list of promises into a single promise that yields a collection.

Say that each promise yields a value of type T, the resulting promise then yields a collection with values of type T.

Here is an example that extracts links from multiple pages and merges the results:

…

When listening for progress events in an All operation, the progress that you will receive will be the average of all the progress values reported by all the given promises.

Chaining Multiple Async Operations

The ThenAll function is a convenient way of chaining multiple promise onto an existing promise:

…

Racing Asynchronous Operations

The Race and ThenRace functions are similar to the All and ThenAll functions, but it is the first async operation that completes that wins the race and it's value resolves the promise.

cs
promise
    .Then(result => SomeAsyncOperation(result)) // Chain an async operation.
    .ThenRace(result =>                         // Race multiple async operations.
        new IPromise[]                  // Return an enumerable of promises.
        {
            SomeAsyncOperation1(result),
            SomeAsyncOperation2(result),
            SomeAsyncOperation3(result)
        }
    )
    .Done(result => ...);                       // The result has come from whichever of
                                                // the async operations completed first.

When listening for progress events in a race operation, the progress that you will receive will be the maximum of those reported by all the given promises.

Chaining Synchronous Actions that have no Result

The Then function can be used to chain synchronous operations that yield no result.

cs
var promise = ...
promise
    .Then(result => SomeAsyncOperation(result)) 	// Chain an async operation.
    .Then(result => Console.WriteLine(result))    	// Chain a sync operation that yields no result.
    .Done(() => ...);  // No result is passed because the previous operation returned nothing.

Promises that have no Results (a non-value promise)

What about a promise that has no result? This represents an asyn

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

C#async-operationc-sharpgame-developmentpromise

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言