Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion Rx.NET/Documentation/IntroToRx/00_Foreword.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,27 @@ Thanks also to those who continued to work on Rx.NET after it ceased to be direc

If you are interested in more information about the origins of Rx, you might find the [A Little History of Reaqtor](https://reaqtive.net/) ebook illuminating.

The version that this book has been written against is `System.Reactive` version 6.0. The source for this book can be found at [https://github.com/dotnet/reactive/tree/main/Rx.NET/Documentation/IntroToRx](https://github.com/dotnet/reactive/tree/main/Rx.NET/Documentation/IntroToRx). If you find any bugs or other issues in this book, please [create an issue](https://github.com/dotnet/reactive/issues) at https://github.com/dotnet/reactive/. You might find the [Reactive X slack](reactivex.slack.com) to be a useful resource if you start using Rx.NET in earnest.
The version that this book has been written against is `System.Reactive` version 6.1. The source for this book can be found at [https://github.com/dotnet/reactive/tree/main/Rx.NET/Documentation/IntroToRx](https://github.com/dotnet/reactive/tree/main/Rx.NET/Documentation/IntroToRx). If you find any bugs or other issues in this book, please [create an issue](https://github.com/dotnet/reactive/issues) at https://github.com/dotnet/reactive/. You might find the [Reactive X slack](reactivex.slack.com) to be a useful resource if you start using Rx.NET in earnest.

So, fire up Visual Studio and let's get started.

# Edition History

## 1st edition

The original book written by Lee Campbell.

## 2nd edition

Updated and revised by Ian Griffiths to align with the Rx v6.0 release.

## 3rd edition

Updates for Rx v6.1:

* Documented new `TakeUntil(CancellationToken)` overload
* Documented new `DiposeWith` extension method for `IDisposable`
* Documented new `ResetExceptionDispatchState` operator
* Added guidance to clarify rules around reusing exception objects in scenarios where Rx will rethrow them

---
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,9 @@ As an example of where you might want to use `Never` for timing purposes, suppos
IObservable<string> throws = Observable.Throw<string>(new Exception());
```

Be aware that this if you use this operator in conjunction with any of the mechanisms described in the [Leaving Rx's World](13_LeavingIObservable.md) chapter, you might fall foul of the rules described in [Exception state](13_LeavingIObservable.md#exception-state). If you need to use `await` (or similar mechanisms that will turn a call to `OnError` into a rethrow) you may need to use the [`ResetExceptionDispatchState`](13_LeavingIObservable.md#resetexceptiondispatchstate) operator to ensure that each rethrowing of the exception gets suitably reset exception state. (This problem only arises if you cause the same exception to be rethrown multiple times.)


### Observable.Create

The `Create` factory method is more powerful than the other creation methods because it can be used to create any kind of sequence. You could implement any of the preceding four methods with `Observable.Create`.
Expand Down Expand Up @@ -516,7 +519,7 @@ public static IObservable<T> Never<T>()
});
}

public static IObservable<T> Throws<T>(Exception exception)
public static IObservable<T> Throw<T>(Exception exception)
{
return Observable.Create<T>(o =>
{
Expand Down Expand Up @@ -1201,6 +1204,9 @@ Sub2: 4

Alternatively, you can specify a time-based limit by passing a `TimeSpan` to the `ReplaySubject<T>` constructor.

Note that if the source reports an error (by calling `OnError`), `ReplaySubject<T>` will retain the `Exception`, and provide it to all current subscribers, and also any subsequent subscribers. This should not be a surprise—this subject's job is to replay what the source did—but be aware that this can cause a problem if you use any of the mechanisms described in the [Leaving Rx's World](13_LeavingIObservable.md) chapter. For example if you `await` an observable that uses a `ReplaySubject<T>` and if the underlying source reported an error, you will no longer be conforming to the rules described in [Exception state](13_LeavingIObservable.md#exception-state). If you need to use `await` (or similar mechanisms that will turn a call to `OnError` into a rethrow) you may need to use the [`ResetExceptionDispatchState`](13_LeavingIObservable.md#resetexceptiondispatchstate) operator to ensure that each rethrowing of the exception gets suitably reset exception state.


## `BehaviorSubject<T>`

Like `ReplaySubject<T>`, `BehaviorSubject<T>` also has a memory, but it remembers exactly one value. However, it's not quite the same as a `ReplaySubject<T>` with a buffer size of 1. Whereas a `ReplaySubject<T>` starts off in a state where it has nothing in its memory, `BehaviorSubject<T>` always remembers _exactly_ one item. How can that work before we've made our first call to `OnNext`? `BehaviorSubject<T>` enforces this by requiring us to supply the initial value when we construct it.
Expand Down
2 changes: 2 additions & 0 deletions Rx.NET/Documentation/IntroToRx/05_Filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ We don't have to use a time, `TakeUntil` offers an overload that accept a second

**Note**: these overloads require the second observable to produce a value in order to trigger the start or end. If that second observable completes without producing a single notification, then it has no effect—`TakeUntil` will continue to take items indefinitely; `SkipUntil` will never produce anything. In other words, these operators would treat `Observable.Empty<T>()` as being effectively equivalent to `Observable.Never<T>()`.

There is also an overload of `TakeUntil` that accepts a `CancellationToken`. This forwards notifications from the source until either the source itself completes, or the token signals cancellation, at which point `TakeUntil` will complete.

### Distinct and DistinctUntilChanged

`Distinct` is yet another standard LINQ operator. It removes duplicates from a sequence. To do this, it needs to remember all the values that its source has ever produced, so that it can filter out any items that it has seen before. Rx includes an implementation of `Distinct`, and this example uses it to display the unique identifier of vessels generating AIS messages, but ensuring that we only display each such identifier the first time we see it:
Expand Down
Loading