Work with events in F #

I recently asked this question: Play the recorded data stream in F # and combine this code with a subset of the functions that I found here: http://www.mattssoftwareblog.com/?p=271 which together looks like this:

#r "System.Reactive"
#r "System.CoreEx"
#r "FSharp.PowerPack"
#r "WindowsBase"
#r "PresentationCore"
#r "PresentationFramework"
#r "System.Xaml"
#r "System.Interactive.dll"

open System
open System.Linq
open System.Collections.Generic
open System.Net
open System.IO
open System.Threading
open System.Windows
open System.Windows.Input
open System.Windows.Controls
open System.Windows.Shapes
open System.Windows.Media
open System.Xaml

I need to use the events generated here (which came from my previous SO question):

let prices = [ (0, 10.0); (1000, 10.5); (500, 9.5); (2500, 8.5); (500, 10.0); (1000, 10.5); (500, 9.5); (2500, 8.5) ]

let evt = new Event<float>()
async { for delay, price in prices do
          do! Async.Sleep(delay)
          evt.Trigger(price) }
        |> Async.StartImmediate

evt.Publish.Add(printfn "Price updated: %A")

for use as a data source for a row that is randomly generated (the code below is in the blog article I mentioned):

let create f =
    Observable.Create<_>(fun x ->
        f x
        new System.Action((fun () -> ())))

let fromEvent (event:IEvent<_,_>) = create (fun x -> event.Add x.OnNext)

// Random Walker
let rand = Random()
let mutable m = 0.
let randomWalker() =
    m <- m + (rand.NextDouble() * 10.) - 5.
    m

let timer = new System.Timers.Timer()
timer.Interval <- 100.
let timerObs = (timer.Elapsed |> fromEvent).Select(fun _ -> randomWalker())

let chartWindow = new Window(Height = 600., Width = 600.)
let canvas = new Canvas()
chartWindow.Content <- canvas
chartWindow.Show()

let line xs =
    let segs =
        seq { for x , y in xs |> List.tail ->
                LineSegment(Point(x,y), true) :> PathSegment }
    let (sx, sy) = xs |> List.head
    PathGeometry([PathFigure(Point(sx,sy), segs, false)])

let plot xs (path:Path) =
    let now = DateTime.Now
    let timeSpan = TimeSpan(0,1,0)
    let width = 600.
    let height = 600.
    let pts = xs |> List.map (fun (x:Timestamped<float>) ->
                (600.-(now - (x.Timestamp.DateTime)).TotalMilliseconds * 600. / timeSpan.TotalMilliseconds),x.Value  + 300.)
    path.Dispatcher.BeginInvoke(new SendOrPostCallback(fun pts -> path.Data <- line (pts :?> (float*float)list)), pts) |> ignore

let trailing (timespan:TimeSpan) (obs:IObservable<'

a>)  =
        obs.Timestamp()
            .Scan([], fun ys x ->
                let now = DateTime.Now
                let timespan = timespan
                x :: (ys |> List.filter (fun x -> (now - x.Timestamp.DateTime) < timespan)))
            .Where(fun xs -> xs |> List.length > 1)

    // Main Path
    let mainPath = new Path(Stroke=Brushes.Blue, StrokeThickness=1.)
    canvas.Children.Add(mainPath)

    let trailingRandomsSub = (timerObs |> trailing (TimeSpan.FromSeconds(60.))).Subscribe(fun xs -> plot xs mainPath)

    timer.Start()

, emerge, evt Event. , , Observable evt. , ?

,

+3
1

F # IEvent<'T> IObservable<'T>. , F # , .

( , , Scan , , , ) :

let trailingRandomsSub = 
  evt.Publish.Timestamp()
  |> Observable.scan (fun l e -> e::l) []
  |> Observable.add (fun xs -> plot xs mainPath)

F # Rx-, Observable.scan, F #. Observable.add Subscribe.

F # - , , . , F #, Async.StartImmediate, StartImmediate ( , , , , ).

+4

All Articles