160 likes | 262 Views
Rozszerzenia reaktywne. Rafał Konrad Pawłaszek. z arządzanie sekwencjami zdarzeń. 16 kwietnia 2013r. Wykorzystanie Rx. Wzorzec obserwatora. Interfejsy podstawowe. public interface IObserver < in T> { void OnNext (T value ); void OnError ( Exception error);
E N D
Rozszerzenia reaktywne Rafał Konrad Pawłaszek zarządzanie sekwencjami zdarzeń 16 kwietnia 2013r.
Interfejsy podstawowe public interfaceIObserver<in T> {voidOnNext(T value); voidOnError(Exception error); voidOnCompleted(); } namespaceSystem { public interfaceIObservable<out T> {IDisposableSubscribe(IObserver<T> observer); } }
Rx i enumeracje IObservable<T> IEnumerable<T> varenu = IEnumerable<int> () => { for (int i = 0; i < 10; i = i + 1) yieldreturn i; }; foreach(var x inenu){Console.WriteLine(x);} varobs = Observable.Generate( 0, i => i < 10, i => i + 1, i => i ); obs.Subscribe(x => { Console.WriteLine(x); });
Rx i enumeracje Rozszerzenia interaktywne (Ix) – implementacja operatorów Rx dla LINQ to Objects
Rx i zdarzenia IObservable<T> event classProgram { eventAction<int> Fire; staticvoidMain() { var p = newProgram(); p.Fire += x => Console.WriteLine(x); p.Fire(16); } } classProgram { ISubject<int> RxFire = newSubject<int>(); staticvoidMain() { var p = newProgram(); p.RxFire.Subscribe(x => { Console.WriteLine(x); }) p.RxFire(16); } }
Rx i zdarzenia namespaceSystem.Reactive.Subjects { publicinterfaceISubject<T> : ISubject<T, T>, IObserver<T>, IObservable<T> { } } W Rx nie zapamiętuje się akcji, aby zakończyć subskrypcje – subskrypcja jest typu IDisposable public static IObservable<EventPattern<object>> FromEventPattern(object target, stringeventName); Typ pierwszoklasowy (http://pl.wikipedia.org/wiki/Typ_pierwszoklasowy): • Może być przechowywany w zmiennych i strukturach danych • Może być przekazywany jako parametr metod • Może być rezultatem wykonania metody • Może być tworzony w czasie działania programu • Posiada tożsamość (niezależną od nazwy)
Zarządzanie współbieżnością newThread(() => { /* akcja */ }).Start() ThreadPool.QueueUserWorkItem(_ => { /* akcja */ }, null) Task.Factory.StartNew(() => { /* akcja */ }); SynchronizationContext.Post(_ => { /* akcja */ }, null) Dispatcher.BeginInvoke(() => { /* akcja */ }); namespaceSystem.Reactive.Concurrency { public interface IScheduler { DateTimeOffsetNow { get; } IDisposableSchedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action); IDisposableSchedule<TState>(TState state, DateTimeOffsetdueTime, Func<IScheduler, TState, IDisposable> action); IDisposableSchedule<TState>(TState state, TimeSpandueTime, Func<IScheduler, TState, IDisposable> action); } }
Zarządzanie współbieżnością Jak z nich skorzystać? SubscribeOn(ISchedulerscheduler) ObserveOn(ISchedulerscheduler)
Co więcej… • Sekwencje historyczne • Testowanie • Rx (rx.codeplex.com) NuGet: Rx-* • Ix (rx.codeplex.com) NuGet: Ix-* • Tx (tx.codeplex.com) NuGet: Tx-* • Qbservable = QueryableObservable • StreamInsight (ICepObservable<T>) • SignalR (Observe)