SlideShare a Scribd company logo
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)
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
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
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
Programação reativa e o actor model
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

More Related Content

PPTX
ZIO: Powerful and Principled Functional Programming in Scala
DOCX
PDF
Second Level Cache in JPA Explained
PDF
PHP 8.1 - What's new and changed
PPTX
JavaScript Fundamentals
PPTX
Thinking Beyond ORM in JPA
PDF
Collections Framework Begineers guide 2
PDF
Julio Capote, Twitter
ZIO: Powerful and Principled Functional Programming in Scala
Second Level Cache in JPA Explained
PHP 8.1 - What's new and changed
JavaScript Fundamentals
Thinking Beyond ORM in JPA
Collections Framework Begineers guide 2
Julio Capote, Twitter

What's hot (20)

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

Similar to Programação reativa e o actor model (20)

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

More from Fabrício Rissetto (8)

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

Recently uploaded (20)

PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Digital Systems & Binary Numbers (comprehensive )
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
PPTX
Transform Your Business with a Software ERP System
PDF
Salesforce Agentforce AI Implementation.pdf
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Cost to Outsource Software Development in 2025
PPTX
history of c programming in notes for students .pptx
PDF
medical staffing services at VALiNTRY
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Autodesk AutoCAD Crack Free Download 2025
PPTX
Oracle Fusion HCM Cloud Demo for Beginners
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Complete Guide to Website Development in Malaysia for SMEs
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Digital Systems & Binary Numbers (comprehensive )
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
Internet Downloader Manager (IDM) Crack 6.42 Build 41
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
Transform Your Business with a Software ERP System
Salesforce Agentforce AI Implementation.pdf
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Cost to Outsource Software Development in 2025
history of c programming in notes for students .pptx
medical staffing services at VALiNTRY
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Autodesk AutoCAD Crack Free Download 2025
Oracle Fusion HCM Cloud Demo for Beginners

Programação reativa e o actor model

  • 1. Programação Reativa e o Actor Model Elemar Júnior @elemarjr [email protected] [email protected] 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)
  • 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
  • 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 [email protected] [email protected] elemarjr.com