Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise equivalent in C#

In Scala there is a Promise class that could be used to complete a Future manually. I am looking for an alternative in C#.

I am writing a test and I want it to look it similar to this:

// var MyResult has a field `Header` var promise = new Promise<MyResult>;  handlerMyEventsWithHandler( msg =>     promise.Complete(msg); );  // Wait for 2 seconds var myResult = promise.Future.Await(2000);  Assert.Equals("my header", myResult.Header); 

I understand that this is probably not the right pattern for C#, but I couldn't figure out a reasonable way to achieve the same thing even with somewhat different pattern.

EDIT: please note, that async/await doesn't help here, as I don't have a Task to await! I just have an access to a handler that will be run on another thread.

like image 588
eddyP23 Avatar asked Aug 17 '16 12:08

eddyP23


People also ask

Is Task same as promise?

Promise is a well-defined built-in object that makes it easy, among other things, to chain synchronous or asynchronous operations. Task is an object defined in trace_viewer/base that can be used to chain synchronous operations. Since both tasks and promises allow chaining operations it's easy to confuse them.

What is a promise in coding?

In programming, Promise means that a program calls a function in the anticipation that it will do some useful thing and return the result which calling program can use. The result or promise is the outcome of calling the function which can be a success or a failure, and the data associated with it.

What is promise design pattern?

The Future design pattern (also called Promise) is a quick and easy way to achieve concurrent structures for asynchronous programming. We will take advantage of first class functions in Go to develop Futures.


1 Answers

In C#:

  • Task<T> is a future (or Task for a unit-returning future).
  • TaskCompletionSource<T> is a promise.

So your code would translate as such:

// var promise = new Promise<MyResult>; var promise = new TaskCompletionSource<MyResult>();  // handlerMyEventsWithHandler(msg => promise.Complete(msg);); handlerMyEventsWithHandler(msg => promise.TrySetResult(msg));  // var myResult = promise.Future.Await(2000); var completed = await Task.WhenAny(promise.Task, Task.Delay(2000)); if (completed == promise.Task)   ; // Do something on timeout var myResult = await completed;  Assert.Equals("my header", myResult.Header); 

The "timed asynchronous wait" is a bit awkward, but it's also relatively uncommon in real-world code. For unit tests, I would just do a regular asynchronous wait:

var promise = new TaskCompletionSource<MyResult>();  handlerMyEventsWithHandler(msg => promise.TrySetResult(msg));  var myResult = await promise.Task;  Assert.Equals("my header", myResult.Header); 
like image 177
Stephen Cleary Avatar answered Sep 25 '22 02:09

Stephen Cleary