Lesson 28 of 40
Advanced C#
Expert
50 min
Reactive Programming with Rx.NET
Model asynchronous event streams with Reactive Extensions (Rx.NET) — observables, operators, schedulers, and real-world use cases.
Part 1: Observables and Observers
// Create observable from events
var mouseClicks = Observable
.FromEventPattern<MouseEventArgs>(window, "MouseClick")
.Select(e => e.EventArgs.GetPosition(null));
mouseClicks.Subscribe(
pos => Console.WriteLine($"Click at {pos}"),
ex => Console.WriteLine("Error: " + ex.Message),
() => Console.WriteLine("Completed"));
var mouseClicks = Observable
.FromEventPattern<MouseEventArgs>(window, "MouseClick")
.Select(e => e.EventArgs.GetPosition(null));
mouseClicks.Subscribe(
pos => Console.WriteLine($"Click at {pos}"),
ex => Console.WriteLine("Error: " + ex.Message),
() => Console.WriteLine("Completed"));
Part 2: Key Operators
| Operator | Description |
|---|---|
| Where | Filter elements |
| Select | Transform elements |
| Throttle/Debounce | Rate limiting |
| Buffer | Group into windows |
| Merge/Zip/CombineLatest | Combine streams |
| Retry/Catch | Error handling |
Part 3: Real-time Search with Debounce
searchBox.TextChanged
.Select(_ => searchBox.Text)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(300))
.SelectMany(term => SearchApiAsync(term))
.ObserveOn(DispatcherScheduler.Current)
.Subscribe(UpdateResults);
.Select(_ => searchBox.Text)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(300))
.SelectMany(term => SearchApiAsync(term))
.ObserveOn(DispatcherScheduler.Current)
.Subscribe(UpdateResults);
Part 4: Schedulers for Threading
Scheduler.CurrentThread— current threadScheduler.ThreadPool— thread poolDispatcherScheduler.Current— UI thread (WPF/MAUI)TaskPoolScheduler.Default— Task poolNewThreadScheduler.Default— dedicated thread per subscription