public
Last active

  • Download Gist
Couroutine.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public static class Coroutine {
 
public static void BeginExecute(IEnumerable<Promise> enumerable) {
MoveNext(enumerable.GetEnumerator());
}
static void MoveNext(IEnumerator<Promise> enumerator) {
if (enumerator.MoveNext()) {
var promise = enumerator.Current;
promise.Current = promise.Task();
promise.Current._CallBack = () => MoveNext(enumerator);
} else {
enumerator.Dispose();
}
}
}
Future.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
public abstract class Future {
private object _value;
public object Value {
get { return _value;}
set { _value = value;
Now();
}
}
 
void Now() {
if (_CallBack == null) throw new InvalidOperationException("_CallBack não foi definido pelo Enumerador");
_CallBack();
}
 
/// <summary>
/// The Coroutine enumerator internally sets this Property to a delegate that points
/// to its continuation delegate, so it can moveNext() the enumerator
/// </summary>
internal Action _CallBack { get; set; }
}
 
public class Future<T> : Future {
public new T Value {
get { return (T)base.Value; }
set { base.Value = value; }
}
}
Promise.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
public abstract class Promise {
public Future Current { get; internal set; }
internal Func<Future> Task { get; private set; }
 
protected Promise(Func<Future> task) {
Task = task;
}
}
public class Promise<T> : Promise {
public new Future<T> Current {
get { return (Future<T>)base.Current; }
internal set { base.Current = value; }
}
 
public Promise(Func<Future<T>> task)
: base(() => task()) {
}
}
asyncKonsole.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
 
namespace AsyncKonsole
{
class Program
{
const bool UsuarioLogado = true;
const string Permissoes = "administrador,operador";
//const string Permissoes = "";
public static void Main(string[] args)
{
//inicia a execução da co-rotina
Coroutine.BeginExecute(Workflow());
//console aguarda execução da rotina
Console.ReadLine();
}
static void CallWebService() {
//simula consulta ao webservice (3 segundos)
Thread.Sleep(3000);
}
static IEnumerable<Promise> Workflow() {
//cria o objeto "promise" construído com uma Func que retorna uma instância de um "future"
var step1 = new Promise<bool>(VerificaUsuarioLogado);
//o enumerador da co-rotina "starta" o delegate referenciado pelo promise, e aguarda sua finalização
yield return step1;
//quando algum valor for setado na instância do "future" contido no "promise", o enumerador avança
//e esta linha é executada, assim podemos ler o valor retornado (bool)
if (step1.Current.Value)
Console.WriteLine("Usuário está logado.");
else {
Console.WriteLine("Usuário não está logado. Fim da rotina.");
yield break; //termina a execução da co-rotina
}
//dessa vez crio uma promise em que o valor esperado é um array de strings
var step2 = new Promise<string[]>(RecuperaPermissoes);
yield return step2;
var permissoes = step2.Current.Value;
foreach (var permissao in permissoes) {
Console.WriteLine(permissao);
}
if (permissoes.Length == 0) {
Console.WriteLine("Sem permissões!");
var step3 = new Promise<object>(MostraTelaLogin);
yield return step3;
yield break; //sai da rotina.
}
else Console.WriteLine("Permissões concedidas");
}
static Future<bool> VerificaUsuarioLogado() {
var future = new Future<bool>();
var task = new Task(CallWebService);
task.ContinueWith(x => {
future.Value = UsuarioLogado; //quando o valor é setado, o enumerador avança
});
task.Start();
return future;
}
static Future<object> MostraTelaLogin() {
var future = new Future<object>();
var task = Task.Factory.StartNew(() => Console.WriteLine("Bem vindo a tela de login"))
.ContinueWith(x => future.Value = null);
return future;
}
static Future<string[]> RecuperaPermissoes() {
var future = new Future<string[]>();
var task = new Task(CallWebService);
task.ContinueWith(x => {
var permissoes = Permissoes.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
future.Value = permissoes;
});
task.Start();
return future;
}
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.