Skip to content

Instantly share code, notes, and snippets.

@lauromoura
Created April 26, 2018 21:27
Show Gist options
  • Save lauromoura/bf873a547d602c1b6af44ccf7204c67f to your computer and use it in GitHub Desktop.
Save lauromoura/bf873a547d602c1b6af44ccf7204c67f to your computer and use it in GitHub Desktop.
Example of wrapping Tasks around futures
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