Condividi tramite


Modulo Control.Observable (F#)

Operazioni di base sul primo evento di classe e su altri oggetti osservabili.

Percorso di spazio dei nomi/modulo: Microsoft.FSharp.Control

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

module Observable

Valori

Valore

Descrizione

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

Crea un osservatore che sottoscrive in modo permanente l'oggetto osservabile specificato e chiama la funzione specificata per ogni osservazione.

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

Restituisce un oggetto osservabile che sceglie una proiezione di osservazioni dall'origine utilizzando la funzione specificata. L'oggetto restituito attiverà osservazioni per le quali il separatore restituisce un valore Some. L'oggetto restituito inoltre propaga tutti gli errori derivanti dall'origine e viene terminato al completamento dell'origine.

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

Restituisce un oggetto osservabile che filtra le osservazioni dell'origine in base alla funzione specificata. Gli oggetti osservabili visualizzeranno solo quelle osservazioni per le quali il predicato restituisce true. Il predicato viene eseguito una volta per ogni osservatore sottoscritto. L'oggetto restituito inoltre propaga le osservazioni sugli errori derivanti dall'origine e viene terminato al completamento dell'origine.

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

Restituisce un oggetto osservabile che trasforma le osservazioni dell'origine in base alla funzione specificata. La funzione di trasformazione viene eseguita una volta per ogni osservatore sottoscritto. L'oggetto restituito inoltre propaga le osservazioni sugli errori derivanti dall'origine e viene terminato al completamento dell'origine.

unione : IObservable<'T> -> IObservable<'T> -> IObservable<'T>

Restituisce un oggetto osservabile per le osservazioni unite dalle origini. L'oggetto restituito propaga i valori di esito positivo e quelli di errore derivanti da entrambe le origini e viene terminato una volta completate le due origini.

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

Restituisce un nuovo oggetto osservabile che attiva la seconda e le successive generazioni dell'oggetto osservabile di input. L'ennesima attivazione dell'osservabile di input passa gli argomenti dalla prima attivazione negativa all'ennesima attivazione come coppia. L'argomento passato alla prima generazione negativa viene mantenuto in uno stato interno nascosto finché non si verifica l'ennesima generazione.

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

Restituisce due oggetti osservabili che eseguono la partizione delle osservazioni dell'origine in base alla funzione specificata. Il primo attiverà le osservazioni per quei valori per i quali il predicato restituisce true. Il secondo attiverà le osservazioni per quei valori in cui il predicato restituisce false. Il predicato viene eseguito una volta per ogni osservatore sottoscritto. Entrambi inoltre propagano tutte le osservazioni sugli errori derivanti dall'origine e ognuno viene terminato al completamento dell'origine.

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

Restituisce un oggetto osservabile che, per ogni osservatore, alloca un elemento di stato e applica la funzione di accumulo specificata ai valori successivi derivanti dall'input. L'oggetto restituito genererà osservazioni per ciascun valore di stato calcolato, escluso il valore iniziale. L'oggetto restituito propaga tutti gli errori derivanti dall'origine e viene terminato al completamento dell'origine.

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

Restituisce due oggetti osservabili che separano le osservazioni dell'origine tramite la funzione specificata. Il primo attiverà osservazioni per le quali il separatore restituisce Choice1Of2. Il secondo attiverà osservazioni y per le quali il separatore restituisce Choice2Of2. Il separatore viene eseguito una volta per ogni osservatore sottoscritto. Entrambi inoltre propagano le osservazioni sugli errori derivanti dall'origine e ognuno viene terminato al completamento dell'origine.

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

Crea un osservatore che sottoscrive l'oggetto osservabile specificato e che chiama la funzione specificata per ogni osservazione.

Esempio

Nell'esempio di codice riportato di seguito viene illustrato l'utilizzo degli oggetti osservabili. La classe ObserverSource definita in questo esempio è una classe riutilizzabile in modo generico ed è possibile utilizzarla come origine degli eventi osservabili. Vengono qui mostrati gli esempi su come utilizzare alcune delle funzioni in questo modulo. Per le funzioni che non sono illustrate, è possibile fare riferimento agli esempi di codice in Modulo Control.Event (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)


Piattaforme

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

Informazioni sulla versione

F# Runtime

Supportato in: 2.0, 4.0

Silverlight

Supportato in: 3

Vedere anche

Riferimenti

Spazio dei nomi Microsoft.FSharp.Control (F#)

Cronologia delle modifiche

Data

Cronologia

Motivo

Ottobre 2010

Aggiunto esempio di codice.

Miglioramento delle informazioni.