- ArchitectNow
Download
Report
Transcript - ArchitectNow
Reactive Extensions (Rx)
Explained
Presenter:
Kevin Grossnicklaus
August 5th, 2011
Agenda
•
•
•
•
Introductions
Talk
Additional Resources
Conclusion
Introductions
• Kevin Grossnicklaus
– ArchitectNow- www.architectnow.net (2009-Present)
• President
– Washington University - CAIT Program (2003-2010)
• Instructor
– SSE - www.SSEinc.com (1999-2009)
• Chief Architect
• Software Development Practice Leader
• Email: [email protected]
• Twitter: @kvgros
• Blog:
blog.architectnow.net
EXPECTATIONS
Expectations
• Experience with .NET development
– Samples will be in C# 4.0
– VS 2010 will be used
• Basic familiarity with LINQ and some Async
programming
• Lambda Expressions will be used
INTRODUCTION TO RX
IEnumerable/IEnumerator
interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
}
interface IEnumerator<T> : IDisposable
{
bool MoveNext();
T Current { get; }
void Reset();
}
Iterating Collections
var items = new string[] { “Hello”, “World” };
foreach (var x in items)
{
//interact with each piece of data
}
//we can now assume we are done
//we must also handle exceptions
IObservable/IObserver
interface IObservable<out T>
{
IDisposable Subscribe(IObserver<T> observer);
}
interface
{
void
void
void
}
IObserver<in T>
OnNext(T value);
OnError(Exception ex);
OnCompleted();
IObservable/IObserver
var _data = new string[] { "Hello", "World" };
var _observable = _data.ToObservable();
var _observer = _observable.Subscribe(x => Console.WriteLine(x));
var _observer2 = _observable.Subscribe(
x => Console.WriteLine(x),
() => Console.WriteLine("Completed"));
var _observer3 = _observable.Subscribe(
x => Console.WriteLine(x),
ex => Console.WriteLine("Exception: " + ex.Message),
() => Console.WriteLine("Completed"));
_observer2.Dispose();
Getting Rx Installed
• NuGet
– Easiest and quickest
• Rx Home Page:
– http://msdn.microsoft.com/en-us/data/gg577609
• Simply add a reference to:
– System.Reactive.DLL
• Available for:
–
–
–
–
–
Full Framework (WPF, WinForms, server side ASP.NET, MVC, etc)
Silverlight 3 and 4
JavaScript
Windows 7 Phone
Xbox/XNA
OBSERVABLE EXTENSIONS
Subjects
using System.Reactive.Subjects;
var _subject = new Subject<string>();
var _observer = _subject.Subscribe(x => Console.WriteLine(x));
_subject.OnNext("Rx");
_subject.OnNext("will");
_subject.OnNext("save");
_subject.OnNext("me");
_subject.OnNext("some");
_subject.OnNext("headaches");
_subject.OnCompleted();
_observer.Dispose();
Subscribing
public static class ObservableExtensions
{
public static IDisposable Subscribe<TSource>(this IObservable<TSource>
source);
public static IDisposable Subscribe<TSource>(this IObservable<TSource>
source, Action<TSource> onNext);
public static IDisposable Subscribe<TSource>(this IObservable<TSource>
source, Action<TSource> onNext, Action<Exception> onError);
public static IDisposable Subscribe<TSource>(this IObservable<TSource>
source, Action<TSource> onNext, Action onCompleted);
public static IDisposable Subscribe<TSource>(this IObservable<TSource>
source, Action<TSource> onNext, Action<Exception> onError, Action
onCompleted);
}
Creation of Observables
//simply call OnComplete
var empty = Observable.Empty<string>();
//Call OnNext(“Value”) and then call OnComplete
var obReturn = Observable.Return("Value");
//Raise no events
var never = Observable.Never<string>();
//Call OnException with the specified expection
var throws = Observable.Throw<string>(new Exception());
//Specify a delegate to be called when anyone subscribes
var createSample = Observable.Create<string>( observable => {
observable.OnNext("a");
observable.OnNext("b");
observable.OnCompleted();
return () => Console.WriteLine("Observer has unsubscribed");
});
Creation of Observables (Cont…)
//Create a range of numbers
var range = Observable.Range(10, 15);
//publish a count from 0 every specified time period
var interval = Observable.Interval(TimeSpan.FromMilliseconds(250));
//Never call “Next” but call “Complete” when the long running operation is done
var longOperation = Observable.Start( x => ..do something that takes awhile.. );
//Generate a collection much like for (i=5, i<15, i+3) return i.ToString();
var generated = Observable.Generate(5, i => i < 15, i => i.ToString(), i => i +
3);
//simply convert an existing collection or array (IEnumerable) to IObservable
var converted = MyCollection.ToObservable();
Rx LINQ Operators
• Where
• Select
• First
•
•
•
•
•
•
•
•
•
•
FirstOrDefault
Last
LastOrDefault
Single
Count
Min
Max
Sum
Where
GroupBy
•
•
•
•
•
•
•
•
•
•
•
Take
TakeUntil
Skip
DistinctUntilChanged
Buffer
Throttle
Sample
Delay
Until
TimeOut
..etc…etc…etc…
RX AND .NET EVENTS
The “Old Way”
txtSample.TextChanged += new TextChangedEventHandler(txtSample_TextChanged);
//txtSample.TextChanged = new TextChangedEventHandler(txtSample_TextChanged);
private string _lastValue = string.Empty;
void txtSample_TextChanged(object sender, TextChangedEventArgs e)
{
var _currentValue = ((TextBox)sender).Text;
if (_currentValue.Length > 5 && _currentValue != _lastValue)
{
_lastValue = _currentValue;
lstData.Items.Add(_currentValue);
}
}
The “New Way”
var _textChanged = Observable
.FromEventPattern<EventArgs>(txtSample, "TextChanged")
.Select(x => ((TextBox)x.Sender).Text);
var _longText = _textChanged
.Where(x => x.Length > 5)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromSeconds(.5));
_longText
.ObserveOnDispatcher()
.Subscribe(x => lstData.Items.Add(x));
ADDITIONAL TOPICS
Additional Topics
• Threading
– Scheduler
• Async Pattern
• Attaching/Detaching
• When should I use Rx?
FINAL THOUGHTS
Additional Resources
•
Rx Homepage
– http://msdn.microsoft.com/en-us/devlabs/gg577609
•
Rx Beginners Guide (Tutorials, Videos, etc)
– http://msdn.microsoft.com/en-us/devlabs/gg577611
•
Great Keynote Overview
– http://channel9.msdn.com/posts/DC2010T0100-Keynote-Rx-curing-your-asynchronousprogramming-blues
•
Team Blog
– http://blogs.msdn.com/b/rxteam/
•
Community Rx Wiki
– http://rxwiki.wikidot.com/
•
Channel 9 Videos
– http://channel9.msdn.com/tags/Rx/
•
RxSandbox
– http://mnajder.blogspot.com/2010/03/rxsandbox-v1.html
•
Great Blog Series by Lee Campbell
– http://leecampbell.blogspot.com/2010/08/reactive-extensions-for-net.html
Next Steps…
[email protected]
Twitter: @kvgros