![]() |
VOOZH | about |
Requires NuGet 2.12 or higher.
dotnet add package System.Reactive --version 6.1.0
NuGet\Install-Package System.Reactive -Version 6.1.0
<PackageReference Include="System.Reactive" Version="6.1.0" />
<PackageVersion Include="System.Reactive" Version="6.1.0" />Directory.Packages.props
<PackageReference Include="System.Reactive" />Project file
paket add System.Reactive --version 6.1.0
#r "nuget: System.Reactive, 6.1.0"
#:package System.Reactive@6.1.0
#addin nuget:?package=System.Reactive&version=6.1.0Install as a Cake Addin
#tool nuget:?package=System.Reactive&version=6.1.0Install as a Cake Tool
Rx enables event-driven programming with a composable, declarative model.
Run the following at a command line:
mkdir TryRx
cd TryRx
dotnet new console
dotnet add package System.Reactive
Alternatively, if you have Visual Studio installed, create a new .NET Console project, and then use the NuGet package manager to add a reference to System.Reactive.
You can then add this code to your Program.cs. This creates an observable source (ticks) that produces an event once every second. It also adds a handler to that source that writes a message to the console for each event:
using System.Reactive.Linq;
IObservable<long> ticks = Observable.Timer(
dueTime: TimeSpan.Zero,
period: TimeSpan.FromSeconds(1));
ticks.Subscribe(
tick => Console.WriteLine($"Tick {tick}"));
Console.ReadLine();
IObservable<T>If you have an existing source of events that does not support Rx directly, but which does offer .NET events, you can bring this into the world of Rx using the Observable.FromEventPattern method:
using System.Reactive.Linq;
FileSystemWatcher fsw = new FileSystemWatcher(@"C:\temp");
IObservable<FileSystemEventArgs> changeEvents = Observable
.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
h => fsw.Changed += h,
h => fsw.Changed -= h)
.Select(e => e.EventArgs);
fsw.EnableRaisingEvents = true;
It can sometimes be useful to wait for a period of inactivity before taking action. For example, if you have code that monitors a directory in a filesystem, processing modified or added files, it's common for there to be flurries of activity. For example, if a user is copying multiple files into a folder that you're observing, there will be multiple changes, and it could be more efficient to wait until those stop and then process all the changes in one batch, than to attempt to process everything immediately.
This example defines a custom Rx operator that can be attached to any source. It will wait for that source to start producing events, and then, it will wait for it to stop again for the specified period. Each time that happens, it reports all of the activity that occurred between the last two periods of inactivity:
static class RxExt
{
public static IObservable<IList<T>> Quiescent<T>(
this IObservable<T> src,
TimeSpan minimumInactivityPeriod,
IScheduler scheduler)
{
IObservable<int> onoffs =
from _ in src
from delta in Observable.Return(1, scheduler).Concat(Observable.Return(-1, scheduler).Delay(minimumInactivityPeriod, scheduler))
select delta;
IObservable<int> outstanding = onoffs.Scan(0, (total, delta) => total + delta);
IObservable<int> zeroCrossings = outstanding.Where(total => total == 0);
return src.Buffer(zeroCrossings);
}
}
(This works by creating a sequence (onoffs) that produces a value 1 each time activity occurs, and then a corresponding -1 after the specified time has elapsed. It then uses Scan to produce the outstanding sequence, which is just a running total of those onoffs. This is effectively a count of the number of events that have happened recently (where 'recently' is defined as 'less than minimumInactivityPeriod ago). Every new event that occurs raises this running total by 1, but each time the specified timespan has passed for a particular event, it drops by one. So when this drops back to 0, it means that there are no events that have occurred as recently as the minimumInactivityPeriod. The zeroCrossings sequence picks out just the events in which outstanding drops back to zero. This has the effect that zeroCrossings raises an event every time there has been some activity followed by minimumInactivityPeriod of inactivity. Finally, we plug this into the Buffer operator, which slices the input events (src) into chunks. By passing it the zeroCrossings source, we tell Buffer to deliver a new slice every time the source becomes inactive. The effect is that the source returned by Quiescent does nothing until there has been some activity followed by the specified period of inactivity, at which point it produces a single event reporting all of the source events that have occurred since the previous period, or in the initial case, all of the source events so far.)
You could use this in conjunction with the adapted FileSystemWatcher from the preceding example:
IObservable<IList<FileSystemEventArgs>> fileActivityStopped = changeEvents
.Quiescent(TimeSpan.FromSeconds(2), Scheduler.Default);
await fileActivityStopped.ForEachAsync(
a => Console.WriteLine($"File changes stopped after {a.Count} changes"));
(Note: this only uses the Changed event. A real application might also need to look at the FileSystemWatcher's Created, Renamed, and Deleted events.)
You can create issues at the https://github.com/dotnet/reactive repository
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net6.0-windows10.0.19041 net6.0-windows10.0.19041 is compatible. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 is compatible. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Universal Windows Platform | uap10.0.18362 uap10.0.18362 is compatible. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on System.Reactive:
| Package | Downloads |
|---|---|
|
System.Reactive.Linq
Legacy facade for Reactive Extensions (Rx) for .NET |
|
|
System.Reactive.Core
Legacy facade for Reactive Extensions (Rx) for .NET |
|
|
System.Reactive.Interfaces
Legacy facade for Reactive Extensions (Rx) for .NET |
|
|
GraphQL.Client
A GraphQL Client for .NET Standard |
|
|
System.Reactive.PlatformServices
Legacy facade for Reactive Extensions (Rx) for .NET |
Showing the top 20 popular GitHub repositories that depend on System.Reactive:
| Repository | Stars |
|---|---|
|
shadowsocks/shadowsocks-windows
A C# port of shadowsocks
|
|
|
AvaloniaUI/Avalonia
Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The future of .NET UI
|
|
|
BeyondDimension/SteamTools
🛠「Watt Toolkit」是一个开源跨平台的多功能 Steam 工具箱。
|
|
|
chocolatey/choco
Chocolatey - the package manager for Windows
|
|
|
Cysharp/UniTask
Provides an efficient allocation free async/await integration for Unity.
|
|
|
dotnet/orleans
Cloud Native application framework for .NET
|
|
|
MathewSachin/Captura
Capture Screen, Audio, Cursor, Mouse Clicks and Keystrokes
|
|
|
unoplatform/uno
Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
|
|
|
reactiveui/refit
The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface.
|
|
|
reactiveui/ReactiveUI
An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms that is inspired by functional reactive programming. ReactiveUI allows you to abstract mutable state away from your user interfaces, express the idea around a feature in one readable place and improve the testability of your application.
|
|
|
gitextensions/gitextensions
Git Extensions is a standalone UI tool for managing git repositories. It also integrates with Windows Explorer and Microsoft Visual Studio (2015/2017/2019).
|
|
|
LykosAI/StabilityMatrix
Multi-Platform Package Manager for Stable Diffusion
|
|
|
PixiEditor/PixiEditor
PixiEditor is a Universal Editor for all your 2D needs
|
|
|
stride3d/stride
Stride (formerly Xenko), a free and open-source cross-platform C# game engine.
|
|
|
louthy/language-ext
C# pure functional programming framework - come and get declarative!
|
|
|
PrismLibrary/Prism
Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
|
|
|
Uahh/ToastFish
一个利用摸鱼时间背单词的软件。
|
|
|
graphql-dotnet/graphql-dotnet
GraphQL for .NET
|
|
|
kurrent-io/KurrentDB
KurrentDB is a database that's engineered for modern software applications and event-driven architectures. Its event-native design simplifies data modeling and preserves data integrity while the integrated streaming engine solves distributed messaging challenges and ensures data consistency.
|
|
|
ChilliCream/graphql-platform
Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Nitro the awesome Monaco based GraphQL IDE.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 7.0.0-rc.1 | 0 | 6/18/2026 |
| 7.0.0-preview.20 | 2,491 | 6/3/2026 |
| 7.0.0-preview.16 | 1,118 | 5/26/2026 |
| 7.0.0-preview.15 | 1,086 | 5/20/2026 |
| 7.0.0-preview.1 | 176,353 | 11/6/2025 |
| 6.1.0 | 7,626,279 | 10/3/2025 |
| 6.1.0-preview.9 | 1,839 | 10/1/2025 |
| 6.0.2 | 1,621,800 | 8/29/2025 |
| 6.0.1 | 46,511,129 | 5/22/2024 |
| 6.0.1-preview.1 | 213,015 | 6/14/2023 |
| 6.0.0 | 53,245,023 | 5/19/2023 |
| 6.0.0-preview.16 | 1,190 | 5/17/2023 |
| 6.0.0-preview.13 | 8,510 | 4/20/2023 |
| 6.0.0-preview.9 | 111,906 | 3/31/2023 |
| 6.0.0-preview.1 | 9,604 | 3/10/2023 |
| 5.0.0 | 103,886,181 | 11/10/2020 |
| 5.0.0-preview.220 | 20,841 | 10/15/2020 |
| 5.0.0-preview.16 | 39,423 | 9/26/2020 |
| 4.4.1 | 71,733,972 | 4/2/2020 |
| 4.3.2 | 33,543,798 | 12/24/2019 |