-
-
Save dbeattie71/051ee6f98f9d64ccc2f4064fea0171ba to your computer and use it in GitHub Desktop.
This file contains hidden or 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.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; | |
} | |
} | |
} |
This file contains hidden or 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
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(); | |
} | |
} | |
} |
This file contains hidden or 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
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; } | |
} | |
} |
This file contains hidden or 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
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()) { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment