Partager via


Control.Observable, module (F#)

Opérations de base sur l'événement de première classe et d'autres objets observables.

Espace de noms/Chemin du module : Microsoft.FSharp.Control

Assembly : FSharp.Core (in FSharp.Core.dll)

module Observable

Valeurs

Valeur

Description

add : ('T -> unit) -> IObservable<'T> -> unit

Crée un observateur qui s'abonne définitivement à l'observable donné et qui appelle la fonction donnée pour chaque observation.

choose : ('T -> 'U option) -> IObservable<'T> -> IObservable<'U>

Retourne un observable qui choisit une projection d'observations dans la source à l'aide de la fonction donnée. L'objet retourné déclenche des observations pour lesquelles le séparateur retourne une valeur Some. L'objet retourné propage également toutes les erreurs émanant de la source et se termine lorsque la source s'achève.

filter : ('T -> bool) -> IObservable<'T> -> IObservable<'T>

Retourne un observable qui filtre les observations de la source selon la fonction donnée. L'observable voit uniquement les observations pour lesquelles le prédicat retourne la valeur true. Le prédicat est exécuté une fois pour chaque observateur abonné. L'objet retourné propage également les observations des erreurs émanant de la source et se termine lorsque la source s'achève.

map : ('T -> 'U) -> IObservable<'T> -> IObservable<'U>

Retourne un observable qui transforme les observations de la source selon la fonction donnée. La fonction de transformation est exécutée une fois pour chaque observateur abonné. L'objet retourné propage également les observations des erreurs émanant de la source et se termine lorsque la source s'achève.

merge : IObservable<'T> -> IObservable<'T> -> IObservable<'T>

Retourne un observable pour les observations fusionnées à partir des sources. L'objet retourné propage les valeurs des erreurs et des réussites qui proviennent de l'une des sources et s'arrête une fois les deux sources terminées.

pairwise : IObservable<'T> -> IObservable<'T * 'T>

Retourne un nouvel observable qui se déclenche à partir du deuxième déclenchement de l'observable d'entrée. Le déclenchement Nth de l'observable d'entrée passe les arguments à partir du déclenchement N-1th et Nth en tant que paire. L'argument passé au déclenchement N-1th est maintenu dans un état interne masqué jusqu'au déclenchement de Nth.

partition : ('T -> bool) -> IObservable<'T> -> IObservable<'T> * IObservable<'T>

Retourne deux observables qui partitionnent les observations de la source selon la fonction donnée. Le premier déclenche des observations pour les valeurs pour lesquelles le prédicat retourne la valeur true. Le second déclenche des observations pour les valeurs pour lesquelles le prédicat retourne la valeur false. Le prédicat est exécuté une fois pour chaque observateur abonné. Les deux propagent également toutes les observations d'erreur provenant de la source et se terminent lorsque la source s'achève.

scan : ('U -> 'T -> 'U) -> 'U -> IObservable<'T> -> IObservable<'T>

Retourne un observable qui, pour chaque observateur, alloue un élément d'état et applique la fonction d'accumulation donnée aux valeurs successives provenant de l'entrée. L'objet retourné déclenche des observations pour chaque valeur d'état calculée, à l'exclusion de la valeur initiale. L'objet retourné propage toutes les erreurs provenant de la source et se termine lorsque la source s'achève.

split : ('T -> Choice<'U1,'U2>) -> IObservable<'T> -> IObservable<'U1> * IObservable<'U2>

Retourne deux observables qui fractionnent les observations de la source selon la fonction donnée. Le premier déclenche des observations pour lesquelles le séparateur retourne Choice1Of2. Le secpmd déclenche des observations y pour lesquelles le séparateur retourne Choice2Of2. Le séparateur est exécuté une fois pour chaque observateur abonné. Les deux propagent également les observations d'erreur provenant de la source et se terminent lorsque la source s'achève.

Subscribe : ('T -> unit) -> IObservable<'T> -> IDisposable

Crée un observateur qui s'abonne à l'observable donné et qui appelle la fonction donnée pour chaque observation.

Exemple

L'exemple de code suivant montre comment utiliser les observables. La classe ObserverSource définie dans cet exemple est une classe réutilisable à caractère général, que vous pouvez utiliser comme source d'événements observables. Des exemples d'utilisation de certaines des fonctions dans ce module sont indiqués ici ; pour les fonctions qui ne sont pas montrées ici, vous pouvez faire référence aux exemples de code dans Control.Event, module (F#).

open System
open System.Diagnostics

// Represents a stream of IObserver events.
type ObservableSource<'T>() =

    let protect function1 =
        let mutable ok = false
        try 
            function1()
            ok <- true
        finally
            Debug.Assert(ok, "IObserver method threw an exception.")

    let mutable key = 0

    // Use a Map, not a Dictionary, because callers might unsubscribe in the OnNext
    // method, so thread-safe snapshots of subscribers to iterate over are needed.
    let mutable subscriptions = Map.empty : Map<int, IObserver<'T>>

    let next(obs) = 
        subscriptions |> Seq.iter (fun (KeyValue(_, value)) -> 
            protect (fun () -> value.OnNext(obs)))

    let completed() = 
        subscriptions |> Seq.iter (fun (KeyValue(_, value)) -> 
            protect (fun () -> value.OnCompleted()))

    let error(err) = 
        subscriptions |> Seq.iter (fun (KeyValue(_, value)) -> 
            protect (fun () -> value.OnError(err)))

    let thisLock = new obj()

    let obs = 
        { new IObservable<'T> with
            member this.Subscribe(obs) =
                let key1 =
                    lock thisLock (fun () ->
                        let key1 = key
                        key <- key + 1
                        subscriptions <- subscriptions.Add(key1, obs)
                        key1)
                { new IDisposable with 
                    member this.Dispose() = 
                        lock thisLock (fun () -> 
                            subscriptions <- subscriptions.Remove(key1)) } }

    let mutable finished = false

    // The source ought to call these methods in serialized fashion (from
    // any thread, but serialized and non-reentrant).
    member this.Next(obs) =
        Debug.Assert(not finished, "IObserver is already finished")
        next obs

    member this.Completed() =
        Debug.Assert(not finished, "IObserver is already finished")
        finished <- true
        completed()

    member this.Error(err) =
        Debug.Assert(not finished, "IObserver is already finished")
        finished <- true
        error err

    // The IObservable object returned is thread-safe; you can subscribe 
    // and unsubscribe (Dispose) concurrently.
    member this.AsObservable = obs

// Create a source.
let source = new ObservableSource<int>()

// Get an IObservable from the source.
let obs = source.AsObservable 

// Add a simple subscriber.
let unsubA = obs |> Observable.subscribe (fun x -> printfn "A: %d" x)

// Send some messages from the source.
// Output: A: 1
source.Next(1)
// Output: A: 2
source.Next(2)

// Add another subscriber. This subscriber has a filter.
let unsubB =
    obs
    |> Observable.filter (fun num -> num % 2 = 0)
    |> Observable.subscribe (fun num -> printfn "B: %d" num)

// Send more messages from the source.
// Output: A: 3
source.Next(3)
// Output: A: 4
//         B: 4
source.Next(4)

// Have subscriber A unsubscribe.
unsubA.Dispose()

// Send more messages from the source.
// No output
source.Next(5)
// Output: B: 6
source.Next(6)

// If you use add, there is no way to unsubscribe from the event.
obs |> Observable.add(fun x -> printfn "C: %d" x)

// Now add a subscriber that only does positive numbers and transforms
// the numbers into another type, here a string.
let unsubD =
    obs |> Observable.choose (fun int1 ->
             if int1 >= 0 then None else Some(int1.ToString()))
        |> Observable.subscribe(fun string1 -> printfn "D: %s" string1)

let unsubE =
    obs |> Observable.filter (fun int1 -> int1 >= 0)
        |> Observable.subscribe(fun int1 -> printfn "E: %d" int1)

let unsubF =
    obs |> Observable.map (fun int1 -> int1.ToString())
        |> Observable.subscribe (fun string1 -> printfn "F: %s" string1)


Plateformes

Windows 7, Windows Vista SP2, Windows XP SP3, Windows XP x64 SP2, Windows Server 2008 R2, Windows Server 2008 SP2, Windows Server 2003 SP2

Informations de version

Runtime F#

Pris en charge dans : 2.0, 4.0

Silverlight

Prise en charge dans : 3

Voir aussi

Référence

Microsoft.FSharp.Control, espace de noms (F#)

Historique des modifications

Date

Historique

Motif

Octobre 2010

Ajout d'un exemple de code

Améliorations apportées aux informations.