Thanks to visit codestin.com
Credit goes to github.com

Skip to content

System.IObservable<T>, IObserver<T> F# snippets #7677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 15, 2022
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
11 changes: 11 additions & 0 deletions snippets/fsharp/System/IObservableT/Overview/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="provider.fs" />
<Compile Include="observer.fs" />
<Compile Include="program.fs" />
</ItemGroup>
</Project>
35 changes: 35 additions & 0 deletions snippets/fsharp/System/IObservableT/Overview/observer.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace global

// <Snippet8>
open System

type LocationReporter(name) =
let mutable unsubscriber = Unchecked.defaultof<IDisposable>

member _.Name = name

member this.Subscribe(provider: IObservable<Location>) =
if provider <> null then
unsubscriber <- provider.Subscribe this

member _.Unsubscribe() =
unsubscriber.Dispose()

interface IObserver<Location> with
// <Snippet11>
member this.OnCompleted() =
printfn $"The Location Tracker has completed transmitting data to {name}."
this.Unsubscribe()
// </Snippet11>

// <Snippet10>
member _.OnError(_) =
printfn $"{name}: The location cannot be determined."
// </Snippet10>

// <Snippet12>
member _.OnNext(value) =
printfn $"{name}: The current location is {value.Latitude}, {value.Longitude}"
// </Snippet12>

// </Snippet8>
24 changes: 24 additions & 0 deletions snippets/fsharp/System/IObservableT/Overview/program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module program

// <Snippet9>
open System

// Define a provider and two observers.
let provider = LocationTracker()
let reporter1 = LocationReporter "FixedGPS"
reporter1.Subscribe provider
let reporter2 = LocationReporter "MobileGPS"
reporter2.Subscribe provider

provider.TrackLocation { Latitude = 47.6456; Longitude = -122.1312 }
reporter1.Unsubscribe()
provider.TrackLocation { Latitude = 47.6677; Longitude = -122.1199 }
provider.TrackLocation(Nullable())
provider.EndTransmission()
// The example displays output similar to the following:
// FixedGPS: The current location is 47.6456, -122.1312
// MobileGPS: The current location is 47.6456, -122.1312
// MobileGPS: The current location is 47.6677, -122.1199
// MobileGPS: The location cannot be determined.
// The Location Tracker has completed transmitting data to MobileGPS.
// </Snippet9>
46 changes: 46 additions & 0 deletions snippets/fsharp/System/IObservableT/Overview/provider.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace global

open System

// <Snippet5>
[<Struct>]
type Location =
{ Latitude: double
Longitude: double }
// </Snippet5>

// <Snippet7>
exception LocationUnknownException
// </Snippet7>

// <Snippet6>
type Unsubscriber(observers: ResizeArray<IObserver<Location>>, observer: IObserver<Location>) =
interface IDisposable with
member _.Dispose() =
if observer <> null && observers.Contains observer then
observers.Remove observer |> ignore

type LocationTracker() =
// <Snippet13>
let observers = ResizeArray<IObserver<Location>>()

interface IObservable<Location> with
member _.Subscribe(observer) =
if observers.Contains observer |> not then
observers.Add observer
new Unsubscriber(observers, observer)

// </Snippet13>
member _.TrackLocation(loc: Nullable<Location>) =
for observer in observers do
if not loc.HasValue then
observer.OnError LocationUnknownException
else
observer.OnNext loc.Value

member _.EndTransmission() =
for observer in observers.ToArray() do
if observers.Contains observer then
observer.OnCompleted()
observers.Clear()
// </Snippet6>
6 changes: 6 additions & 0 deletions xml/System/IObservable`1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,33 @@
The following example illustrates the observer design pattern. It defines a `Location` class that contains latitude and longitude information.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet5":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet5":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet5":::

The `LocationTracker` class provides the <xref:System.IObservable%601> implementation. Its `TrackLocation` method is passed a nullable `Location` object that contains the latitude and longitude data. If the `Location` value is not `null`, the `TrackLocation` method calls the <xref:System.IObserver%601.OnNext%2A> method of each observer.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet6":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet6":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet6":::

If the `Location` value is `null`, the `TrackLocation` method instantiates a `LocationUnknownException` object, which is shown in the following example. It then calls each observer's <xref:System.IObserver%601.OnError%2A> method and passes it the `LocationUnknownException` object. Note that `LocationUnknownException` derives from <xref:System.Exception>, but does not add any new members.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet7":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet7":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet7":::

Observers register to receive notifications from a `TrackLocation` object by calling its <xref:System.IObservable%601.Subscribe%2A?displayProperty=nameWithType> method, which assigns a reference to the observer object to a private generic <xref:System.Collections.Generic.List%601> object. The method returns an `Unsubscriber` object, which is an <xref:System.IDisposable> implementation that enables observers to stop receiving notifications. The `LocationTracker` class also includes an `EndTransmission` method. When no further location data is available, the method calls each observer's <xref:System.IObserver%601.OnCompleted%2A> method and then clears the internal list of observers.

In this example, the `LocationReporter` class provides the <xref:System.IObserver%601> implementation. It displays information about the current location to the console. Its constructor includes a `name` parameter, which enables the `LocationReporter` instance to identify itself in its string output. It also includes a `Subscribe` method, which wraps a call to the provider's <xref:System.IObservable%601.Subscribe%2A> method. This allows the method to assign the returned <xref:System.IDisposable> reference to a private variable. The `LocationReporter` class also includes an `Unsubscribe` method, which calls the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method of the object that is returned by the <xref:System.IObservable%601.Subscribe%2A?displayProperty=nameWithType> method. The following code defines the `LocationReporter` class.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/observer.cs" id="Snippet8":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/observer.fs" id="Snippet8":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/observer.vb" id="Snippet8":::

The following code then instantiates the provider and the observer.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/program.cs" id="Snippet9":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/program.fs" id="Snippet9":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/module1.vb" id="Snippet9":::

]]></format>
Expand Down Expand Up @@ -155,6 +160,7 @@
The following example illustrates the <xref:System.IObservable%601.Subscribe%2A> method for an application that reports latitude and longitude information. It defines an <xref:System.Collections.Generic.IList%601> collection object that stores references to all observers. It also returns a private class named `Unsubscriber` that implements the <xref:System.IDisposable> interface and enables subscribers to stop receiving event notifications. See the Example section of the <xref:System.IObservable%601> topic for the complete example.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet13":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet13":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet13":::

]]></format>
Expand Down
8 changes: 8 additions & 0 deletions xml/System/IObserver`1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,28 +65,33 @@
The following example illustrates the observer design pattern. It defines a `Location` class that contains latitude and longitude information.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet5":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet5":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet5":::

The `LocationReporter` class provides the <xref:System.IObserver%601> implementation. It displays information about the current location to the console. Its constructor includes a `name` parameter, which allows the `LocationReporter` instance to identify itself in its string output. It also includes a `Subscribe` method, which wraps a call to the provider's <xref:System.IObservable%601.Subscribe%2A> method. This enables the method to assign the returned <xref:System.IDisposable> reference to a private variable. The `LocationReporter` class also includes an `Unsubscribe` method, which calls the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method of the object returned by the <xref:System.IObservable%601.Subscribe%2A?displayProperty=nameWithType> method. The following code defines the `LocationReporter` class.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/observer.cs" id="Snippet8":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/observer.fs" id="Snippet8":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/observer.vb" id="Snippet8":::

The `LocationTracker` class provides the <xref:System.IObservable%601> implementation. Its `TrackLocation` method is passed a nullable `Location` object that contains the latitude and longitude data. If the `Location` value is not `null`, the `TrackLocation` method calls the <xref:System.IObserver%601.OnNext%2A> method of each observer.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet6":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet6":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet6":::

If the `Location` value is `null`, the `TrackLocation` method instantiates a `LocationNotFoundException` object, which is shown in the following example. It then calls each observer's <xref:System.IObserver%601.OnError%2A> method and passes it the `LocationNotFoundException` object. Note that `LocationNotFoundException` derives from <xref:System.Exception> but does not add any new members.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/provider.cs" id="Snippet7":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/provider.fs" id="Snippet7":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/provider.vb" id="Snippet7":::

Observers register to receive notifications from a `TrackLocation` object by calling its <xref:System.IObservable%601.Subscribe%2A?displayProperty=nameWithType> method, which assigns a reference to the observer object to a private generic <xref:System.Collections.Generic.List%601> object. The method returns an `Unsubscriber` object, which is an <xref:System.IDisposable> implementation that enables observers to stop receiving notifications. The `LocationTracker` class also includes an `EndTransmission` method. When no further location data is available, the method calls each observer's <xref:System.IObserver%601.OnCompleted%2A> method and then clears the internal list of observers.

The following code then instantiates the provider and the observer.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/program.cs" id="Snippet9":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/program.fs" id="Snippet9":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/module1.vb" id="Snippet9":::

]]></format>
Expand Down Expand Up @@ -142,6 +147,7 @@
The following example provides an implementation of the <xref:System.IObserver%601.OnCompleted%2A> method in a latitude/longitude tracking application. The method simply reports that no further data is available and calls the provider's <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation. See the Example section of the <xref:System.IObserver%601> topic for the complete example.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/observer.cs" id="Snippet11":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/observer.fs" id="Snippet11":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/observer.vb" id="Snippet11":::

]]></format>
Expand Down Expand Up @@ -199,6 +205,7 @@
The following example provides an implementation of the <xref:System.IObserver%601.OnError%2A> method in a latitude/longitude tracking application. The method simply reports that data is currently unavailable; it does not make use of the <xref:System.Exception> object passed to it as a parameter. See the Example section of the <xref:System.IObserver%601> topic for the complete example.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/observer.cs" id="Snippet10":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/observer.fs" id="Snippet10":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/observer.vb" id="Snippet10":::

]]></format>
Expand Down Expand Up @@ -256,6 +263,7 @@
The following example provides an implementation of the <xref:System.IObserver%601.OnNext%2A> method in a latitude/longitude tracking application. See the Example section of the <xref:System.IObserver%601> topic for the complete example.

:::code language="csharp" source="~/snippets/csharp/System/IObservableT/Overview/observer.cs" id="Snippet12":::
:::code language="fsharp" source="~/snippets/fsharp/System/IObservableT/Overview/observer.fs" id="Snippet12":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.iobserver.class/vb/observer.vb" id="Snippet12":::

]]></format>
Expand Down