Created
April 26, 2018 21:27
-
-
Save lauromoura/bf873a547d602c1b6af44ccf7204c67f to your computer and use it in GitHub Desktop.
Example of wrapping Tasks around futures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading.Tasks; | |
class FutureProducer | |
{ | |
public int Counter {get; private set; } | |
private eina.Promise Promise; | |
public FutureProducer() | |
{ | |
} | |
// Would-be eo method that returns an eina.Future | |
public eina.Future Produce() | |
{ | |
Promise = new eina.Promise(); | |
return new eina.Future(Promise); | |
} | |
// Triggers the promise resolution upon a loop iteration | |
public void FullfilProduce() | |
{ | |
using (eina.Value v = new eina.Value(eina.ValueType.Int32)) | |
{ | |
v.Set(Counter++); | |
Promise.Resolve(v); | |
Promise = null; | |
} | |
} | |
// async wrapper around the method returning an eina.Future. | |
public Task<eina.Value> ProduceAsync() | |
{ | |
eina.Future future = Produce(); | |
// Creates a task that will wait for SetResult for completion. | |
var tcs = new TaskCompletionSource<eina.Value>(); | |
future.Then((eina.Value received) => { | |
tcs.SetResult(received); // Will mark the returned task below as completed. | |
return received; | |
}); | |
return tcs.Task; | |
} | |
} | |
class FutureConsumer | |
{ | |
// Regular future consumer. In practice, an async consumer as the actual | |
// work is inside the Then callback. | |
public void Consume(FutureProducer p) | |
{ | |
eina.Future future = p.Produce(); | |
future.Then((eina.Value v) => { | |
int x; | |
v.Get(out x); | |
return v; | |
}); | |
} | |
} | |
class AsyncConsumer | |
{ | |
// Async as it will wait for the Task wrapping a future to complete and do | |
// something with its value. | |
public async Task ConsumeAsync(FutureProducer p) | |
{ | |
Task<eina.Value> task = p.ProduceAsync(); | |
eina.Value v = await task; | |
int x; | |
v.Get(out x); | |
} | |
} | |
class Program | |
{ | |
public static void Main() | |
{ | |
efl.All.Init(); | |
MainFuture(); | |
MainAsync(); | |
efl.All.Shutdown(); | |
} | |
public static void MainAsync() | |
{ | |
efl.Loop loop = efl.AppConcrete.GetLoopMain(); | |
FutureProducer p = new FutureProducer(); | |
AsyncConsumer c = new AsyncConsumer(); | |
Task t = c.ConsumeAsync(p); | |
p.FullfilProduce(); | |
loop.Iterate(); // Will trigger the promise resolution and call the future callbacks. | |
t.Wait(); // Synchronization point with the returned task. | |
efl.All.Shutdown(); | |
} | |
public static void MainFuture() | |
{ | |
efl.All.Init(); | |
efl.Loop loop = efl.AppConcrete.GetLoopMain(); | |
FutureProducer p = new FutureProducer(); | |
FutureConsumer c = new FutureConsumer(); | |
c.Consume(p); | |
p.FullfilProduce(); | |
loop.Iterate(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment