SlideShare uma empresa Scribd logo
1 de 142
Programação Reativa e o
Actor Model
Elemar Júnior
@elemarjr
elemarjr@ravendb.net
elemarjr@gmail.com
elemarjr.com
Olá, eu sou Elemar Jr
Abstrações...
Antes de entender o que é
Programação Reativa, vamos
entender o que não é!
public static string[] GetNamesFromEmployees(Employee[] employees)
{
var result = new string[employees.Length];
for (var i = 0; i < employees.Length; i++)
{
result[i] = employees[i].Name;
}
return result;
}
public static string[] GetNamesFromEmployees(Employee[] employees)
{
var result = new string[employees.Length];
for (var i = 0; i < employees.Length; i++)
{
result[i] = employees[i].Name;
}
return result;
}
public static List<string> GetNamesFromEmployees(List<Employee> employees)
{
var result = new List<string>(employees.Count);
foreach (var employee in employees)
{
result.Add(employee.Name);
}
return result;
}
public static IList<string> GetNamesFromEmployees(IList<Employee> employees)
{
var result = new List<string>(employees.Count);
foreach (var employee in employees)
{
result.Add(employee.Name);
}
return result;
}
public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees)
{
var result = new List<string>();
foreach (var employee in employees)
{
result.Add(employee.Name);
}
return result;
}
public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees)
{
var result = new List<string>();
foreach (var employee in employees)
{
result.Add(employee.Name);
}
return result;
}
public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees)
{
foreach (var employee in employees)
{
yield return employee.Name;
}
}
PAUSA PARA ENTENDER...
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
1
After Yield 1
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
1
After Yield 1
Before Yield 2
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
Before calling Get4
After calling Get4
Before Yield 1
1
After Yield 1
Before Yield 2
...
VOLTAMOS...
public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees)
{
foreach (var employee in employees)
{
yield return employee.Name;
}
}
public static class EnumerableOfEmployees
{
public static IEnumerable<string> GetNames(IEnumerable<Employee> employees)
{
foreach (var employee in employees)
{
yield return employee.Name;
}
}
}
EnumerableOfEmployees.GetNames(someListOfEmployees);
public static class EnumerableOfEmployees
{
public static IEnumerable<string> GetNames(
this IEnumerable<Employee> employees
)
{
foreach (var employee in employees)
{
yield return employee.Name;
}
}
}
var names = someListOfEmployees.GetNames();
var names = EnumerableOfEmployees.GetNames(someListOfEmployees);
public static class EnumerableOfEmployees
{
public static IEnumerable<string> GetNames(
this IEnumerable<Employee> employees
)
{
foreach (var employee in employees)
{
yield return employee.Name;
}
}
public static IEnumerable<string> GetSocialSecurityNumbers(
this IEnumerable<Employee> employees
)
{
foreach (var employee in employees)
{
yield return employee.SocialSecurityNumber;
}
}
}
public static class EnumerableOfEmployees
{
public static IEnumerable<string> GetNames(
this IEnumerable<Employee> employees
)
{
foreach (var employee in employees)
{
yield return employee.Name;
}
}
public static IEnumerable<string> GetSocialSecurityNumbers(
this IEnumerable<Employee> employees
)
{
foreach (var employee in employees)
{
yield return employee.SocialSecurityNumber;
}
}
}
public static class EnumerableOfEmployees
{
public static IEnumerable<TResult> Get<TResult>(
this IEnumerable<Employee> employees,
Func<Employee, TResult> selector
)
{
foreach (var employee in employees)
{
yield return selector(employee);
}
}
}
var names = someListOfEmployees.Get(e => e.Name);
var ssn = someListOfEmployees.Get(e => e.SocialSecurityNumber);
public static class EnumerableOfEmployees
{
public static IEnumerable<TResult> Get<TResult>(
this IEnumerable<Employee> employees,
Func<Employee, TResult> selector
)
{
foreach (var employee in employees)
{
yield return selector(employee);
}
}
}
public static class Enumerable
{
public static IEnumerable<TResult> Get<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
public static class Enumerable
{
public static IEnumerable<TResult> Get<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
public static class Enumerable
{
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
LINQPara objetos em memória
public static class Enumerable
{
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
var names = someListOfEmployees.Select(e => e.Name);
var ssn = someListOfEmployees.Select(e => e.SocialSecurityNumber);
public static IEnumerable<T> Where<T>(
this IEnumerable<T> elements,
Func<T, bool> filter
)
{
foreach (var element in elements)
{
if (filter(element))
{
yield return element;
}
}
}
public static IEnumerable<T> Take<T>(
this IEnumerable<T> elements,
int count
)
{
var i = 0;
foreach (var element in elements)
{
if (i >= count) yield break;
yield return element;
i++;
}
}
public static class Enumerable
{
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public static class Enumerable
{
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public static class Enumerable
{
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
foreach (var element in elements)
{
yield return selector(element);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable, IEnumerator
{
T Current { get; }
}
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
)
{
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
yield return selector(enumerator.Current);
}
}
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
) => new SelectEnumerable<T, TResult>(elements, selector);
class SelectEnumerable<T, TResult> : IEnumerable<TResult>
{
private readonly IEnumerable<T> _elements;
private readonly Func<T, TResult> _selector;
public SelectEnumerable(
IEnumerable<T> elements,
Func<T, TResult> selector
)
{
_elements = elements;
_selector = selector;
}
public IEnumerator<TResult> GetEnumerator()
=> new SelectEnumerator(_elements.GetEnumerator(), _selector);
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
) => new SelectEnumerable<T, TResult>(elements, selector);
class SelectEnumerable<T, TResult> : IEnumerable<TResult>
{
private readonly IEnumerable<T> _elements;
private readonly Func<T, TResult> _selector;
public SelectEnumerable(
IEnumerable<T> elements,
Func<T, TResult> selector
)
{
_elements = elements;
_selector = selector;
}
public IEnumerator<TResult> GetEnumerator()
=> new SelectEnumerator(_elements.GetEnumerator, _selector);
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
var names = someEmployees.Select(e => e.Name);
foreach (var name in names)
{
Console.WriteLine(name);
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
public static IEnumerable<TResult> Select<T, TResult>(
this IEnumerable<T> elements,
Func<T, TResult> selector
) => new SelectEnumerable<T, TResult>(elements, selector);
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
} class SelectEnumerable<T, TResult> : IEnumerable<TResult>
{
private readonly IEnumerable<T> _elements;
private readonly Func<T, TResult> _selector;
public SelectEnumerable(
IEnumerable<T> elements,
Func<T, TResult> selector
)
{
_elements = elements;
_selector = selector;
}
public IEnumerator<TResult> GetEnumerator()
=> new SelectEnumerator(_elements.GetEnumerator, _selector);
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
var names = someEmployees.Select(e => e.Name);
using (var enumerator = names.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
class WhereEnumerator<T> : IEnumerator<T>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, bool> _filter;
public WhereEnumerator(
IEnumerator<T> source,
Func<T, bool> filter
)
{
_source = source;
_filter = filter;
}
public void Dispose() => _source.Dispose();
public bool MoveNext()
{
while (_source.MoveNext())
if (_filter(_source.Current))
return true;
return false;
}
public void Reset() => _source.Reset();
public T Current => _source.Current;
object IEnumerator.Current => Current;
}
class WhereEnumerator<T> : IEnumerator<T>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, bool> _filter;
public WhereEnumerator(
IEnumerator<T> source,
Func<T, bool> filter
)
{
_source = source;
_filter = filter;
}
public void Dispose() => _source.Dispose();
public bool MoveNext()
{
while (_source.MoveNext())
if (_filter(_source.Current))
return true;
return false;
}
public void Reset() => _source.Reset();
public T Current => _source.Current;
object IEnumerator.Current => Current;
}
class SelectEnumerator<T, TResult> : IEnumerator<TResult>
{
private readonly IEnumerator<T> _source;
private readonly Func<T, TResult> _selector;
public SelectEnumerator(
IEnumerator<T> source,
Func<T, TResult> selector
)
{
_source = source;
_selector = selector;
}
public void Dispose() => _source.Dispose();
public bool MoveNext() => _source.MoveNext();
public void Reset() => _source.Dispose();
public TResult Current => _selector(_source.Current);
object IEnumerator.Current => Current;
}
PAUSA PARA ENTENDER...
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
public static IEnumerable<int> Get4()
=> new Get4Enumerable();
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
using System.Collections.Generic;
using static System.Console;
public class Program
{
public static void Main()
{
WriteLine("Before calling Get4");
var elements = Get4();
WriteLine("After calling Get4");
foreach (var e in elements)
{
WriteLine(e);
}
}
public static IEnumerable<int> Get4()
{
for (var i = 1; i <= 4; i++)
{
WriteLine($"Before Yield {i}");
yield return i;
WriteLine($"After Yield {i}");
}
}
}
class Get4Enumerator : IEnumerator<int>
{
private int _state;
private int _current;
public void Dispose() { }
bool IEnumerator.MoveNext()
{
if (_state == 1) WriteLine($"After Yield {_current}");
if (_current >= 4)
{
_state = 2;
return false;
}
_current++;
WriteLine($"Before Yield {_current}");
_state = 1;
return true;
}
public void Reset() { _current = 0; }
public int Current => _current;
object IEnumerator.Current => Current;
}
VOLTAMOS...
Where Select ConsumerProducer
Where Select ConsumerProducer
GetEnumerator()
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
Where Select ConsumerProducer
GetEnumerator()GetEnumerator()
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
Where Select ConsumerProducer
GetEnumerator()GetEnumerator()GetEnumerator()
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
Where Select ConsumerProducer
MoveNext()
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
Where Select ConsumerProducer
MoveNext()MoveNext()
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
Where Select ConsumerProducer
MoveNext()MoveNext()MoveNext()
using (var enumerator = elements.GetEnumerator())
{
while (enumerator.MoveNext())
{
WriteLine(enumerator.Current);
}
}
Consumidor Comanda
Estamos habituados a desenvolver
código “pró-ativo”
Mas por que se fala tanto em
programação “reativa”?
Usuários esperam resultados em
real-time
Eventos são cidadãos de primeira
grandeza.
Eventos são cidadãos de primeira
grandeza
User Interface
Eventos são cidadãos de primeira
grandeza
Domain Events
Eventos são cidadãos de primeira
grandeza
Infrastructure Events
Eventos são cidadãos de primeira
grandeza
Integration Events (Bus)
Erik Meijer
Where Select ConsumerProducer
IEnumerableIEnumerableIEnumerable
Where Select ConsumerProducer
IEnumerableIEnumerableIEnumerable
IObservableIObservableIObservable
Where Select ConsumerProducer
IEnumerableIEnumerableIEnumerable
IObservableIObservableIObservable
public interface IObservable<out T>
{
IDisposable Subscribe(IObserver<T> observer);
}
Where Select ConsumerProducer
IEnumerableIEnumerableIEnumerable
IObservableIObservableIObservable
public interface IObservable<out T>
{
IDisposable Subscribe(IObserver<T> observer);
}
IObserver
IObserverIObserver
public interface IObserver<in T>
{
void OnCompleted();
void OnError(Exception error);
void OnNext(T value);
}
Where Select ConsumerProducer
Subscribe()
Where Select ConsumerProducer
Subscribe()Subscribe()
Where Select ConsumerProducer
Subscribe()Subscribe()Subscribe()
Where Select ConsumerProducer
OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted
Where Select ConsumerProducer
OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted
Produtor Comanda
Exemplo 1: Abstrações para APIs
primitivas
public class Bytes : IObservable<byte>
{
private readonly NetworkStream _stream;
private readonly Subject<byte> _subject;
private Bytes(NetworkStream stream)
{
_stream = stream;
_subject = new Subject<byte>();
}
private bool _running;
private async void Run()
{
_running = true;
var buffer = new byte[8192];
try
{
int bytesRead;
while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);
}
catch (Exception e)
{
_subject.OnError(e);
}
_subject.OnCompleted();
}
private readonly object _guard = new object();
public IDisposable Subscribe(IObserver<byte> observer)
{
lock (_guard)
{
var result = _subject.Subscribe(observer);
if (!_running) Run();
return result;
}
}
public static Bytes From(NetworkStream stream)
=> new Bytes(stream);
}
public class Bytes : IObservable<byte>
{
private readonly NetworkStream _stream;
private readonly Subject<byte> _subject;
private Bytes(NetworkStream stream)
{
_stream = stream;
_subject = new Subject<byte>();
}
public class Bytes : IObservable<byte>
{
private readonly NetworkStream _stream;
private readonly Subject<byte> _subject;
private Bytes(NetworkStream stream)
{
_stream = stream;
_subject = new Subject<byte>();
}
private bool _running;
private async void Run()
{
_running = true;
var buffer = new byte[8192];
try
{
int bytesRead;
while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);
}
catch (Exception e)
{
_subject.OnError(e);
}
_subject.OnCompleted();
}
private readonly object _guard = new object();
public IDisposable Subscribe(IObserver<byte> observer)
{
lock (_guard)
{
var result = _subject.Subscribe(observer);
if (!_running) Run();
return result;
}
}
public static Bytes From(NetworkStream stream)
=> new Bytes(stream);
}
private readonly object _guard = new object();
public IDisposable Subscribe(IObserver<byte> observer)
{
lock (_guard)
{
var result = _subject.Subscribe(observer);
if (!_running) Run();
return result;
}
}
public static Bytes From(NetworkStream stream)
=> new Bytes(stream);
public class Bytes : IObservable<byte>
{
private readonly NetworkStream _stream;
private readonly Subject<byte> _subject;
private Bytes(NetworkStream stream)
{
_stream = stream;
_subject = new Subject<byte>();
}
private bool _running;
private async void Run()
{
_running = true;
var buffer = new byte[8192];
try
{
int bytesRead;
while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);
}
catch (Exception e)
{
_subject.OnError(e);
}
_subject.OnCompleted();
}
private readonly object _guard = new object();
public IDisposable Subscribe(IObserver<byte> observer)
{
lock (_guard)
{
var result = _subject.Subscribe(observer);
if (!_running) Run();
return result;
}
}
public static Bytes From(NetworkStream stream)
=> new Bytes(stream);
}
private bool _running;
private async void Run()
{
_running = true;
var buffer = new byte[8192];
try
{
int bytesRead;
while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);
}
}
catch (Exception e)
{
_subject.OnError(e);
}
_subject.OnCompleted();
}
public class FramedMessages : IObservable<string>
{
enum States {Expecting254, Expecting255 };
private readonly Subject<string> _subject;
private FramedMessages(IObservable<byte> bytes)
{
_subject = new Subject<string>();
var buffer = new MemoryStream();
var currentState = States.Expecting254;
bytes.Subscribe(new AnonymousObserver<byte>(
onNext: b =>
{
if (currentState == States.Expecting254)
{
if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b);
}
else
{
if (b == 255)
{
currentState = States.Expecting254;
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
buffer = new MemoryStream();
}
else
{
buffer.WriteByte(254);
buffer.WriteByte(255);
}
}
},
onCompleted: () =>
{
var a = buffer.ToArray();
if (a.Length != 0)
{
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
}
_subject.OnCompleted();
}
));
}
public IDisposable Subscribe(IObserver<string> observer)
=> _subject.Subscribe(observer);
public static FramedMessages From(IObservable<byte> bytes)
=> new FramedMessages(bytes);
}
public class FramedMessages : IObservable<string>
{
enum States { Expecting254, Expecting255 };
private readonly Subject<string> _subject;
private FramedMessages(IObservable<byte> bytes)
{
_subject = new Subject<string>();
var buffer = new MemoryStream();
var currentState = States.Expecting254;
public class FramedMessages : IObservable<string>
{
enum States {Expecting254, Expecting255 };
private readonly Subject<string> _subject;
private FramedMessages(IObservable<byte> bytes)
{
_subject = new Subject<string>();
var buffer = new MemoryStream();
var currentState = States.Expecting254;
bytes.Subscribe(new AnonymousObserver<byte>(
onNext: b =>
{
if (currentState == States.Expecting254)
{
if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b);
}
else
{
if (b == 255)
{
currentState = States.Expecting254;
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
buffer = new MemoryStream();
}
else
{
buffer.WriteByte(254);
buffer.WriteByte(255);
}
}
},
onCompleted: () =>
{
var a = buffer.ToArray();
if (a.Length != 0)
{
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
}
_subject.OnCompleted();
}
));
}
public IDisposable Subscribe(IObserver<string> observer)
=> _subject.Subscribe(observer);
public static FramedMessages From(IObservable<byte> bytes)
=> new FramedMessages(bytes);
}
bytes.Subscribe(new AnonymousObserver<byte>(
onNext: b =>
{
if (currentState == States.Expecting254)
{
if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b);
}
else
{
if (b == 255)
{
currentState = States.Expecting254;
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
buffer = new MemoryStream();
}
else
{
buffer.WriteByte(254);
buffer.WriteByte(255);
}
}
},
public class FramedMessages : IObservable<string>
{
enum States {Expecting254, Expecting255 };
private readonly Subject<string> _subject;
private FramedMessages(IObservable<byte> bytes)
{
_subject = new Subject<string>();
var buffer = new MemoryStream();
var currentState = States.Expecting254;
bytes.Subscribe(new AnonymousObserver<byte>(
onNext: b =>
{
if (currentState == States.Expecting254)
{
if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b);
}
else
{
if (b == 255)
{
currentState = States.Expecting254;
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
buffer = new MemoryStream();
}
else
{
buffer.WriteByte(254);
buffer.WriteByte(255);
}
}
},
onCompleted: () =>
{
var a = buffer.ToArray();
if (a.Length != 0)
{
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
}
_subject.OnCompleted();
}
));
}
public IDisposable Subscribe(IObserver<string> observer)
=> _subject.Subscribe(observer);
public static FramedMessages From(IObservable<byte> bytes)
=> new FramedMessages(bytes);
}
onCompleted: () =>
{
var a = buffer.ToArray();
if (a.Length != 0)
{
var message = Encoding.UTF8.GetString(buffer.ToArray());
_subject.OnNext(message);
}
_subject.OnCompleted();
}
Exemplo 2: Tratamento inteligente
de eventos de UI (JavaScript)
Exemplo 3: Gerenciando fluxo de
dados de API externa
var framesGrabbed =
Observable.FromEventPattern(
h => _capturer.ImageGrabbed += h,
h => _capturer.ImageGrabbed -= h
)
.Sample(TimeSpan.FromSeconds(1));
// frame to bitmap
var bitmaps = framesGrabbed.Select(
args => ((Capture)args.Sender).QueryFrame().Bitmap
);
Exemplo 4: Combinando eventos I
var form = this;
var mouseDown = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
h => form.MouseDown += h,
h => form.MouseDown -= h
);
var mouseUp = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
h => form.MouseUp += h,
h => form.MouseUp -= h
);
var mouseMove = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
h => form.MouseMove += h,
h => form.MouseMove -= h
);
var dragging =
from down in mouseDown
from move in mouseMove.TakeUntil(mouseUp)
select new
{
Start = down.EventArgs.Location,
Finish = move.EventArgs.Location
};
var subscription = dragging.Subscribe(info =>
{
using (Graphics g = form.CreateGraphics())
g.DrawLine(Pens.Red, info.Start, info.Finish);
});
Exemplo 5: Reconhecendo
sequências
var keyUp = Observable.FromEventPattern<KeyEventHandler, KeyEventArgs>(
h => form.KeyUp += h,
h => form.KeyUp -= h
)
.Select(key => key.EventArgs.KeyCode);
Func<Keys, IObservable<Keys>> WherePressedIs =
(searchedKey) => keyUp.Where(k => k == searchedKey);
Func<Keys, IObservable<Keys>> WherePressedIsNot =
(searchedKey) => keyUp.Where(k => k != searchedKey);
var abcPressed =
from fst in WherePressedIs(Keys.A)
from snd in WherePressedIs(Keys.B).Take(1).TakeUntil(WherePressedIsNot(Keys.B))
from thd in WherePressedIs(Keys.C).Take(1).TakeUntil(WherePressedIsNot(Keys.C))
select new Unit();
Adotando Actor Model
Ele foi definido em 1973 por Carl
Hewitt
Define uma abstração para Sistemas
Distribuídos e Concorrentes
Foi popularizado na linguagem
ERLANG
class CapturerActor : ReceiveActor
{
private readonly IActorRef _recognizer;
public CapturerActor(IActorRef recognizer)
{
_recognizer = recognizer;
Waiting();
}
private void Waiting()
{
Receive<Messages.StartCapturingMessage>(m =>
{
Execute();
Become(Running);
});
}
private void Running()
{
Receive<Messages.StopCapturingMessage>(m =>
{
_handler.Dispose();
_capturer.Dispose();
Become(Stopped);
});
}
private void Stopped() { }
private Capture _capturer;
private IDisposable _handler;
public void Execute()
{
_capturer = new Capture();
WriteLine();
// get a frame per second
var framesGrabbed =
Observable.FromEventPattern(
h => _capturer.ImageGrabbed += h,
h => _capturer.ImageGrabbed -= h
)
.Sample(TimeSpan.FromSeconds(1));
// frame to bitmap
var bitmaps = framesGrabbed.Select(
args => ((Capture)args.Sender).QueryFrame().Bitmap
);
_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));
_capturer.Start();
}
}
class CapturerActor : ReceiveActor
{
private readonly IActorRef _recognizer;
public CapturerActor(IActorRef recognizer)
{
_recognizer = recognizer;
Waiting();
}
private void Waiting()
{
Receive<Messages.StartCapturingMessage>(m =>
{
Execute();
Become(Running);
});
}
class CapturerActor : ReceiveActor
{
private readonly IActorRef _recognizer;
public CapturerActor(IActorRef recognizer)
{
_recognizer = recognizer;
Waiting();
}
private void Waiting()
{
Receive<Messages.StartCapturingMessage>(m =>
{
Execute();
Become(Running);
});
}
private void Running()
{
Receive<Messages.StopCapturingMessage>(m =>
{
_handler.Dispose();
_capturer.Dispose();
Become(Stopped);
});
}
private void Stopped() { }
private Capture _capturer;
private IDisposable _handler;
public void Execute()
{
_capturer = new Capture();
WriteLine();
// get a frame per second
var framesGrabbed =
Observable.FromEventPattern(
h => _capturer.ImageGrabbed += h,
h => _capturer.ImageGrabbed -= h
)
.Sample(TimeSpan.FromSeconds(1));
// frame to bitmap
var bitmaps = framesGrabbed.Select(
args => ((Capture)args.Sender).QueryFrame().Bitmap
);
_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));
_capturer.Start();
}
}
private void Running()
{
Receive<Messages.StopCapturingMessage>(m =>
{
_handler.Dispose();
_capturer.Dispose();
Become(Stopped);
});
}
class CapturerActor : ReceiveActor
{
private readonly IActorRef _recognizer;
public CapturerActor(IActorRef recognizer)
{
_recognizer = recognizer;
Waiting();
}
private void Waiting()
{
Receive<Messages.StartCapturingMessage>(m =>
{
Execute();
Become(Running);
});
}
private void Running()
{
Receive<Messages.StopCapturingMessage>(m =>
{
_handler.Dispose();
_capturer.Dispose();
Become(Stopped);
});
}
private void Stopped() { }
private Capture _capturer;
private IDisposable _handler;
public void Execute()
{
_capturer = new Capture();
WriteLine();
// get a frame per second
var framesGrabbed =
Observable.FromEventPattern(
h => _capturer.ImageGrabbed += h,
h => _capturer.ImageGrabbed -= h
)
.Sample(TimeSpan.FromSeconds(1));
// frame to bitmap
var bitmaps = framesGrabbed.Select(
args => ((Capture)args.Sender).QueryFrame().Bitmap
);
_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));
_capturer.Start();
}
}
private Capture _capturer;
private IDisposable _handler;
public void Execute()
{
// configuring the camera
_capturer = new Capture();
// get a frame per second
var framesGrabbed =
Observable.FromEventPattern(
h => _capturer.ImageGrabbed += h,
h => _capturer.ImageGrabbed -= h
)
.Sample(TimeSpan.FromSeconds(1));
// frame to bitmap
var bitmaps = framesGrabbed.Select(
args => ((Capture)args.Sender).QueryFrame().Bitmap
);
_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));
_capturer.Start();
}
_myActorSystem = ActorSystem.Create(“MyActorSystem");
var props = Props.Create(() => new RecognizerActor())
.WithRouter(new RoundRobinPool(10));
var recognizer = _myActorSystem
.ActorOf(props, "recognizer");
var capturer = _myActorSystem
.ActorOf(Props.Create(() => new CapturerActor(recognizer)), "capturer");
capturer.Tell(Messages.StartCapturing());
elemarjr.com
@elemarjr
linkedin.com/in/elemarjr
elemarjr@ravendb.net
elemarjr@gmail.com
Mantenha contato!
Programação Reativa e o
Actor Model
Elemar Júnior
@elemarjr
elemarjr@ravendb.net
elemarjr@gmail.com
elemarjr.com

Mais conteúdo relacionado

Mais procurados

Evaluating Hype in scala
Evaluating Hype in scalaEvaluating Hype in scala
Evaluating Hype in scalaPere Villega
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
Lazy vs. Eager Loading Strategies in JPA 2.1
Lazy vs. Eager Loading Strategies in JPA 2.1Lazy vs. Eager Loading Strategies in JPA 2.1
Lazy vs. Eager Loading Strategies in JPA 2.1Patrycja Wegrzynowicz
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava SchmidtJavaDayUA
 
Unbreakable: The Craft of Code
Unbreakable: The Craft of CodeUnbreakable: The Craft of Code
Unbreakable: The Craft of CodeJoe Morgan
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
 
Developing RESTful Services in .NET
Developing RESTful Services in .NETDeveloping RESTful Services in .NET
Developing RESTful Services in .NETRobert MacLean
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Ignacio Martín
 
Building Maintainable Applications in Apex
Building Maintainable Applications in ApexBuilding Maintainable Applications in Apex
Building Maintainable Applications in ApexJeffrey Kemp
 
Iterators & Generators in ECMAScript 6.0
Iterators & Generators in ECMAScript 6.0Iterators & Generators in ECMAScript 6.0
Iterators & Generators in ECMAScript 6.0Eyal Vardi
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesFederico Feroldi
 

Mais procurados (20)

Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Thinking Beyond ORM in JPA
Thinking Beyond ORM in JPAThinking Beyond ORM in JPA
Thinking Beyond ORM in JPA
 
Evaluating Hype in scala
Evaluating Hype in scalaEvaluating Hype in scala
Evaluating Hype in scala
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
Lazy vs. Eager Loading Strategies in JPA 2.1
Lazy vs. Eager Loading Strategies in JPA 2.1Lazy vs. Eager Loading Strategies in JPA 2.1
Lazy vs. Eager Loading Strategies in JPA 2.1
 
API first with Swagger and Scala by Slava Schmidt
API first with Swagger and Scala by  Slava SchmidtAPI first with Swagger and Scala by  Slava Schmidt
API first with Swagger and Scala by Slava Schmidt
 
jdbc
jdbcjdbc
jdbc
 
Arrays matrix 2020 ab
Arrays matrix 2020 abArrays matrix 2020 ab
Arrays matrix 2020 ab
 
Unbreakable: The Craft of Code
Unbreakable: The Craft of CodeUnbreakable: The Craft of Code
Unbreakable: The Craft of Code
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Developing RESTful Services in .NET
Developing RESTful Services in .NETDeveloping RESTful Services in .NET
Developing RESTful Services in .NET
 
C Prog - Array
C Prog - ArrayC Prog - Array
C Prog - Array
 
Command Liner with Scala
Command Liner with ScalaCommand Liner with Scala
Command Liner with Scala
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6Redux saga: managing your side effects. Also: generators in es6
Redux saga: managing your side effects. Also: generators in es6
 
Building Maintainable Applications in Apex
Building Maintainable Applications in ApexBuilding Maintainable Applications in Apex
Building Maintainable Applications in Apex
 
Iterators & Generators in ECMAScript 6.0
Iterators & Generators in ECMAScript 6.0Iterators & Generators in ECMAScript 6.0
Iterators & Generators in ECMAScript 6.0
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
A Blueprint for Scala Microservices
A Blueprint for Scala MicroservicesA Blueprint for Scala Microservices
A Blueprint for Scala Microservices
 

Semelhante a Programação reativa e o actor model

Functional programming basics
Functional programming basicsFunctional programming basics
Functional programming basicsopenbala
 
OrderTest.javapublic class OrderTest {       Get an arra.pdf
OrderTest.javapublic class OrderTest {         Get an arra.pdfOrderTest.javapublic class OrderTest {         Get an arra.pdf
OrderTest.javapublic class OrderTest {       Get an arra.pdfakkhan101
 
Basic java, java collection Framework and Date Time API
Basic java, java collection Framework and Date Time APIBasic java, java collection Framework and Date Time API
Basic java, java collection Framework and Date Time APIjagriti srivastava
 
2. Create a Java class called EmployeeMain within the same project Pr.docx
 2. Create a Java class called EmployeeMain within the same project Pr.docx 2. Create a Java class called EmployeeMain within the same project Pr.docx
2. Create a Java class called EmployeeMain within the same project Pr.docxajoy21
 
SeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovySeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovyTed Leung
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveNaresha K
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz Hasan
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETtdc-globalcode
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBtdc-globalcode
 
Object oriented programming (first)
Object oriented programming (first)Object oriented programming (first)
Object oriented programming (first)Hvatrex Hamam
 
JDI 2.0. Not only UI testing
JDI 2.0. Not only UI testingJDI 2.0. Not only UI testing
JDI 2.0. Not only UI testingCOMAQA.BY
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
SOLID principles with Typescript examples
SOLID principles with Typescript examplesSOLID principles with Typescript examples
SOLID principles with Typescript examplesAndrew Nester
 
import java-util--- public class MyLinkedList{ public static void.pdf
import java-util---  public class MyLinkedList{    public static void.pdfimport java-util---  public class MyLinkedList{    public static void.pdf
import java-util--- public class MyLinkedList{ public static void.pdfasarudheen07
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript FunctionsColin DeCarlo
 

Semelhante a Programação reativa e o actor model (20)

Functional programming basics
Functional programming basicsFunctional programming basics
Functional programming basics
 
OrderTest.javapublic class OrderTest {       Get an arra.pdf
OrderTest.javapublic class OrderTest {         Get an arra.pdfOrderTest.javapublic class OrderTest {         Get an arra.pdf
OrderTest.javapublic class OrderTest {       Get an arra.pdf
 
Basic java, java collection Framework and Date Time API
Basic java, java collection Framework and Date Time APIBasic java, java collection Framework and Date Time API
Basic java, java collection Framework and Date Time API
 
Initial Java Core Concept
Initial Java Core ConceptInitial Java Core Concept
Initial Java Core Concept
 
Tugas algoritma fibonacci
Tugas algoritma   fibonacciTugas algoritma   fibonacci
Tugas algoritma fibonacci
 
2. Create a Java class called EmployeeMain within the same project Pr.docx
 2. Create a Java class called EmployeeMain within the same project Pr.docx 2. Create a Java class called EmployeeMain within the same project Pr.docx
2. Create a Java class called EmployeeMain within the same project Pr.docx
 
SeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovySeaJUG March 2004 - Groovy
SeaJUG March 2004 - Groovy
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain Effective
 
Java 5 and 6 New Features
Java 5 and 6 New FeaturesJava 5 and 6 New Features
Java 5 and 6 New Features
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
 
Object oriented programming (first)
Object oriented programming (first)Object oriented programming (first)
Object oriented programming (first)
 
JDI 2.0. Not only UI testing
JDI 2.0. Not only UI testingJDI 2.0. Not only UI testing
JDI 2.0. Not only UI testing
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
SOLID principles with Typescript examples
SOLID principles with Typescript examplesSOLID principles with Typescript examples
SOLID principles with Typescript examples
 
import java-util--- public class MyLinkedList{ public static void.pdf
import java-util---  public class MyLinkedList{    public static void.pdfimport java-util---  public class MyLinkedList{    public static void.pdf
import java-util--- public class MyLinkedList{ public static void.pdf
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 

Mais de Fabrício Rissetto

Functional Domain Driven Design
Functional Domain Driven DesignFunctional Domain Driven Design
Functional Domain Driven DesignFabrício Rissetto
 
Domain Driven Design: Zero to Hero
Domain Driven Design: Zero to HeroDomain Driven Design: Zero to Hero
Domain Driven Design: Zero to HeroFabrício Rissetto
 
Kotlin: conhecendo features de uma linguagem moderna
Kotlin: conhecendo features de uma linguagem modernaKotlin: conhecendo features de uma linguagem moderna
Kotlin: conhecendo features de uma linguagem modernaFabrício Rissetto
 
Threads tasks e o tal do thread pool
Threads tasks e o tal do thread poolThreads tasks e o tal do thread pool
Threads tasks e o tal do thread poolFabrício Rissetto
 
Threads Tasks e o tal do Thread Pool
Threads Tasks e o tal do Thread PoolThreads Tasks e o tal do Thread Pool
Threads Tasks e o tal do Thread PoolFabrício Rissetto
 

Mais de Fabrício Rissetto (8)

Functional Domain Driven Design
Functional Domain Driven DesignFunctional Domain Driven Design
Functional Domain Driven Design
 
Domain Driven Design: Zero to Hero
Domain Driven Design: Zero to HeroDomain Driven Design: Zero to Hero
Domain Driven Design: Zero to Hero
 
Kotlin: conhecendo features de uma linguagem moderna
Kotlin: conhecendo features de uma linguagem modernaKotlin: conhecendo features de uma linguagem moderna
Kotlin: conhecendo features de uma linguagem moderna
 
Construindo um Context Map
Construindo um Context MapConstruindo um Context Map
Construindo um Context Map
 
Threads tasks e o tal do thread pool
Threads tasks e o tal do thread poolThreads tasks e o tal do thread pool
Threads tasks e o tal do thread pool
 
Threads Tasks e o tal do Thread Pool
Threads Tasks e o tal do Thread PoolThreads Tasks e o tal do Thread Pool
Threads Tasks e o tal do Thread Pool
 
DDD - Cicatrizes de guerra
DDD - Cicatrizes de guerraDDD - Cicatrizes de guerra
DDD - Cicatrizes de guerra
 
Web Scraping
Web ScrapingWeb Scraping
Web Scraping
 

Último

%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Hararemasabamasaba
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 

Último (20)

%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare%in Harare+277-882-255-28 abortion pills for sale in Harare
%in Harare+277-882-255-28 abortion pills for sale in Harare
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 

Programação reativa e o actor model

  • 1. Programação Reativa e o Actor Model Elemar Júnior @elemarjr elemarjr@ravendb.net elemarjr@gmail.com elemarjr.com
  • 2. Olá, eu sou Elemar Jr
  • 4. Antes de entender o que é Programação Reativa, vamos entender o que não é!
  • 5. public static string[] GetNamesFromEmployees(Employee[] employees) { var result = new string[employees.Length]; for (var i = 0; i < employees.Length; i++) { result[i] = employees[i].Name; } return result; }
  • 6. public static string[] GetNamesFromEmployees(Employee[] employees) { var result = new string[employees.Length]; for (var i = 0; i < employees.Length; i++) { result[i] = employees[i].Name; } return result; }
  • 7. public static List<string> GetNamesFromEmployees(List<Employee> employees) { var result = new List<string>(employees.Count); foreach (var employee in employees) { result.Add(employee.Name); } return result; }
  • 8. public static IList<string> GetNamesFromEmployees(IList<Employee> employees) { var result = new List<string>(employees.Count); foreach (var employee in employees) { result.Add(employee.Name); } return result; }
  • 9. public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees) { var result = new List<string>(); foreach (var employee in employees) { result.Add(employee.Name); } return result; }
  • 10. public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees) { var result = new List<string>(); foreach (var employee in employees) { result.Add(employee.Name); } return result; }
  • 11. public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees) { foreach (var employee in employees) { yield return employee.Name; } }
  • 13. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } }
  • 14. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4
  • 15. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4
  • 16. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4
  • 17. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4
  • 18. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4
  • 19. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4
  • 20. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4
  • 21. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4
  • 22. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1
  • 23. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1
  • 24. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1
  • 25. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1
  • 26. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1 1
  • 27. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1 1
  • 28. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1 1
  • 29. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1 1 After Yield 1
  • 30. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1 1 After Yield 1 Before Yield 2
  • 31. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } Before calling Get4 After calling Get4 Before Yield 1 1 After Yield 1 Before Yield 2 ...
  • 33. public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees) { foreach (var employee in employees) { yield return employee.Name; } }
  • 34. public static class EnumerableOfEmployees { public static IEnumerable<string> GetNames(IEnumerable<Employee> employees) { foreach (var employee in employees) { yield return employee.Name; } } } EnumerableOfEmployees.GetNames(someListOfEmployees);
  • 35. public static class EnumerableOfEmployees { public static IEnumerable<string> GetNames( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.Name; } } } var names = someListOfEmployees.GetNames(); var names = EnumerableOfEmployees.GetNames(someListOfEmployees);
  • 36. public static class EnumerableOfEmployees { public static IEnumerable<string> GetNames( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.Name; } } public static IEnumerable<string> GetSocialSecurityNumbers( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.SocialSecurityNumber; } } }
  • 37. public static class EnumerableOfEmployees { public static IEnumerable<string> GetNames( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.Name; } } public static IEnumerable<string> GetSocialSecurityNumbers( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.SocialSecurityNumber; } } }
  • 38. public static class EnumerableOfEmployees { public static IEnumerable<TResult> Get<TResult>( this IEnumerable<Employee> employees, Func<Employee, TResult> selector ) { foreach (var employee in employees) { yield return selector(employee); } } } var names = someListOfEmployees.Get(e => e.Name); var ssn = someListOfEmployees.Get(e => e.SocialSecurityNumber);
  • 39. public static class EnumerableOfEmployees { public static IEnumerable<TResult> Get<TResult>( this IEnumerable<Employee> employees, Func<Employee, TResult> selector ) { foreach (var employee in employees) { yield return selector(employee); } } }
  • 40. public static class Enumerable { public static IEnumerable<TResult> Get<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } }
  • 41. public static class Enumerable { public static IEnumerable<TResult> Get<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } }
  • 42. public static class Enumerable { public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } }
  • 44. public static class Enumerable { public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } } var names = someListOfEmployees.Select(e => e.Name); var ssn = someListOfEmployees.Select(e => e.SocialSecurityNumber);
  • 45. public static IEnumerable<T> Where<T>( this IEnumerable<T> elements, Func<T, bool> filter ) { foreach (var element in elements) { if (filter(element)) { yield return element; } } }
  • 46. public static IEnumerable<T> Take<T>( this IEnumerable<T> elements, int count ) { var i = 0; foreach (var element in elements) { if (i >= count) yield break; yield return element; i++; } }
  • 47. public static class Enumerable { public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
  • 48. public static class Enumerable { public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } }
  • 49. public static class Enumerable { public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } } public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
  • 50. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } }
  • 51. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } } public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
  • 52. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } } public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
  • 53. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } } public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
  • 54. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } } public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
  • 55. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } } public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { T Current { get; } } public interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); }
  • 56. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } } }
  • 57. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) => new SelectEnumerable<T, TResult>(elements, selector); class SelectEnumerable<T, TResult> : IEnumerable<TResult> { private readonly IEnumerable<T> _elements; private readonly Func<T, TResult> _selector; public SelectEnumerable( IEnumerable<T> elements, Func<T, TResult> selector ) { _elements = elements; _selector = selector; } public IEnumerator<TResult> GetEnumerator() => new SelectEnumerator(_elements.GetEnumerator(), _selector); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); }
  • 58. public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) => new SelectEnumerable<T, TResult>(elements, selector); class SelectEnumerable<T, TResult> : IEnumerable<TResult> { private readonly IEnumerable<T> _elements; private readonly Func<T, TResult> _selector; public SelectEnumerable( IEnumerable<T> elements, Func<T, TResult> selector ) { _elements = elements; _selector = selector; } public IEnumerator<TResult> GetEnumerator() => new SelectEnumerator(_elements.GetEnumerator, _selector); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 59. var names = someEmployees.Select(e => e.Name); foreach (var name in names) { Console.WriteLine(name); } var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } }
  • 60. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } }
  • 61. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) => new SelectEnumerable<T, TResult>(elements, selector);
  • 62. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } }
  • 63. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerable<T, TResult> : IEnumerable<TResult> { private readonly IEnumerable<T> _elements; private readonly Func<T, TResult> _selector; public SelectEnumerable( IEnumerable<T> elements, Func<T, TResult> selector ) { _elements = elements; _selector = selector; } public IEnumerator<TResult> GetEnumerator() => new SelectEnumerator(_elements.GetEnumerator, _selector); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); }
  • 64. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 65. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 66. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 67. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 68. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 69. var names = someEmployees.Select(e => e.Name); using (var enumerator = names.GetEnumerator()) { while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); } } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 70. class WhereEnumerator<T> : IEnumerator<T> { private readonly IEnumerator<T> _source; private readonly Func<T, bool> _filter; public WhereEnumerator( IEnumerator<T> source, Func<T, bool> filter ) { _source = source; _filter = filter; } public void Dispose() => _source.Dispose(); public bool MoveNext() { while (_source.MoveNext()) if (_filter(_source.Current)) return true; return false; } public void Reset() => _source.Reset(); public T Current => _source.Current; object IEnumerator.Current => Current; }
  • 71. class WhereEnumerator<T> : IEnumerator<T> { private readonly IEnumerator<T> _source; private readonly Func<T, bool> _filter; public WhereEnumerator( IEnumerator<T> source, Func<T, bool> filter ) { _source = source; _filter = filter; } public void Dispose() => _source.Dispose(); public bool MoveNext() { while (_source.MoveNext()) if (_filter(_source.Current)) return true; return false; } public void Reset() => _source.Reset(); public T Current => _source.Current; object IEnumerator.Current => Current; } class SelectEnumerator<T, TResult> : IEnumerator<TResult> { private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector; public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; } public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current; }
  • 73. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } public static IEnumerable<int> Get4() => new Get4Enumerable();
  • 74. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } }
  • 75. using System.Collections.Generic; using static System.Console; public class Program { public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } } public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } } } class Get4Enumerator : IEnumerator<int> { private int _state; private int _current; public void Dispose() { } bool IEnumerator.MoveNext() { if (_state == 1) WriteLine($"After Yield {_current}"); if (_current >= 4) { _state = 2; return false; } _current++; WriteLine($"Before Yield {_current}"); _state = 1; return true; } public void Reset() { _current = 0; } public int Current => _current; object IEnumerator.Current => Current; }
  • 78. Where Select ConsumerProducer GetEnumerator() using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } }
  • 79. Where Select ConsumerProducer GetEnumerator()GetEnumerator() using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } }
  • 80. Where Select ConsumerProducer GetEnumerator()GetEnumerator()GetEnumerator() using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } }
  • 81. Where Select ConsumerProducer MoveNext() using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } }
  • 82. Where Select ConsumerProducer MoveNext()MoveNext() using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } }
  • 83. Where Select ConsumerProducer MoveNext()MoveNext()MoveNext() using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { WriteLine(enumerator.Current); } } Consumidor Comanda
  • 84. Estamos habituados a desenvolver código “pró-ativo”
  • 85. Mas por que se fala tanto em programação “reativa”?
  • 87. Eventos são cidadãos de primeira grandeza.
  • 88. Eventos são cidadãos de primeira grandeza User Interface
  • 89. Eventos são cidadãos de primeira grandeza Domain Events
  • 90. Eventos são cidadãos de primeira grandeza Infrastructure Events
  • 91. Eventos são cidadãos de primeira grandeza Integration Events (Bus)
  • 95. Where Select ConsumerProducer IEnumerableIEnumerableIEnumerable IObservableIObservableIObservable public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); }
  • 96. Where Select ConsumerProducer IEnumerableIEnumerableIEnumerable IObservableIObservableIObservable public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); } IObserver IObserverIObserver public interface IObserver<in T> { void OnCompleted(); void OnError(Exception error); void OnNext(T value); }
  • 100. Where Select ConsumerProducer OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted
  • 101. Where Select ConsumerProducer OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted Produtor Comanda
  • 102. Exemplo 1: Abstrações para APIs primitivas
  • 103. public class Bytes : IObservable<byte> { private readonly NetworkStream _stream; private readonly Subject<byte> _subject; private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); } private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]); } catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); } private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } } public static Bytes From(NetworkStream stream) => new Bytes(stream); } public class Bytes : IObservable<byte> { private readonly NetworkStream _stream; private readonly Subject<byte> _subject; private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); }
  • 104. public class Bytes : IObservable<byte> { private readonly NetworkStream _stream; private readonly Subject<byte> _subject; private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); } private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]); } catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); } private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } } public static Bytes From(NetworkStream stream) => new Bytes(stream); } private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } } public static Bytes From(NetworkStream stream) => new Bytes(stream);
  • 105. public class Bytes : IObservable<byte> { private readonly NetworkStream _stream; private readonly Subject<byte> _subject; private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); } private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]); } catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); } private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } } public static Bytes From(NetworkStream stream) => new Bytes(stream); } private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) { for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]); } } catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); }
  • 106. public class FramedMessages : IObservable<string> { enum States {Expecting254, Expecting255 }; private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254; bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } }, onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); } )); } public IDisposable Subscribe(IObserver<string> observer) => _subject.Subscribe(observer); public static FramedMessages From(IObservable<byte> bytes) => new FramedMessages(bytes); } public class FramedMessages : IObservable<string> { enum States { Expecting254, Expecting255 }; private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254;
  • 107. public class FramedMessages : IObservable<string> { enum States {Expecting254, Expecting255 }; private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254; bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } }, onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); } )); } public IDisposable Subscribe(IObserver<string> observer) => _subject.Subscribe(observer); public static FramedMessages From(IObservable<byte> bytes) => new FramedMessages(bytes); } bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } },
  • 108. public class FramedMessages : IObservable<string> { enum States {Expecting254, Expecting255 }; private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254; bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } }, onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); } )); } public IDisposable Subscribe(IObserver<string> observer) => _subject.Subscribe(observer); public static FramedMessages From(IObservable<byte> bytes) => new FramedMessages(bytes); } onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); }
  • 109. Exemplo 2: Tratamento inteligente de eventos de UI (JavaScript)
  • 110.
  • 111.
  • 112.
  • 113.
  • 114. Exemplo 3: Gerenciando fluxo de dados de API externa
  • 115. var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1));
  • 116. // frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap );
  • 117. Exemplo 4: Combinando eventos I
  • 118. var form = this; var mouseDown = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => form.MouseDown += h, h => form.MouseDown -= h ); var mouseUp = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => form.MouseUp += h, h => form.MouseUp -= h ); var mouseMove = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => form.MouseMove += h, h => form.MouseMove -= h );
  • 119. var dragging = from down in mouseDown from move in mouseMove.TakeUntil(mouseUp) select new { Start = down.EventArgs.Location, Finish = move.EventArgs.Location };
  • 120. var subscription = dragging.Subscribe(info => { using (Graphics g = form.CreateGraphics()) g.DrawLine(Pens.Red, info.Start, info.Finish); });
  • 122. var keyUp = Observable.FromEventPattern<KeyEventHandler, KeyEventArgs>( h => form.KeyUp += h, h => form.KeyUp -= h ) .Select(key => key.EventArgs.KeyCode);
  • 123. Func<Keys, IObservable<Keys>> WherePressedIs = (searchedKey) => keyUp.Where(k => k == searchedKey); Func<Keys, IObservable<Keys>> WherePressedIsNot = (searchedKey) => keyUp.Where(k => k != searchedKey);
  • 124. var abcPressed = from fst in WherePressedIs(Keys.A) from snd in WherePressedIs(Keys.B).Take(1).TakeUntil(WherePressedIsNot(Keys.B)) from thd in WherePressedIs(Keys.C).Take(1).TakeUntil(WherePressedIsNot(Keys.C)) select new Unit();
  • 126. Ele foi definido em 1973 por Carl Hewitt
  • 127. Define uma abstração para Sistemas Distribuídos e Concorrentes
  • 128. Foi popularizado na linguagem ERLANG
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137. class CapturerActor : ReceiveActor { private readonly IActorRef _recognizer; public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); } private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); } private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); } private void Stopped() { } private Capture _capturer; private IDisposable _handler; public void Execute() { _capturer = new Capture(); WriteLine(); // get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1)); // frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap ); _handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap)); _capturer.Start(); } } class CapturerActor : ReceiveActor { private readonly IActorRef _recognizer; public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); } private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); }
  • 138. class CapturerActor : ReceiveActor { private readonly IActorRef _recognizer; public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); } private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); } private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); } private void Stopped() { } private Capture _capturer; private IDisposable _handler; public void Execute() { _capturer = new Capture(); WriteLine(); // get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1)); // frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap ); _handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap)); _capturer.Start(); } } private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); }
  • 139. class CapturerActor : ReceiveActor { private readonly IActorRef _recognizer; public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); } private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); } private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); } private void Stopped() { } private Capture _capturer; private IDisposable _handler; public void Execute() { _capturer = new Capture(); WriteLine(); // get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1)); // frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap ); _handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap)); _capturer.Start(); } } private Capture _capturer; private IDisposable _handler; public void Execute() { // configuring the camera _capturer = new Capture(); // get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1)); // frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap ); _handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap)); _capturer.Start(); }
  • 140. _myActorSystem = ActorSystem.Create(“MyActorSystem"); var props = Props.Create(() => new RecognizerActor()) .WithRouter(new RoundRobinPool(10)); var recognizer = _myActorSystem .ActorOf(props, "recognizer"); var capturer = _myActorSystem .ActorOf(Props.Create(() => new CapturerActor(recognizer)), "capturer"); capturer.Tell(Messages.StartCapturing());
  • 142. Programação Reativa e o Actor Model Elemar Júnior @elemarjr elemarjr@ravendb.net elemarjr@gmail.com elemarjr.com