Non-blocking Chart.Show in FSharp.Charting - asynchronous

Using FSharp.Charting from a .fs program, when a plot is displayed it blocks the execution of rest of the program. Is there a way to generate non blocking charts? E.g. I would want both the following to be displayed in separate windows and also have the rest of the program execute.
Chart.Line(Series1) |> Chart.Show // Chart 1
// do some work
Chart.Line(Series2) |> Chart.Show // display this in a second window
// continue executing the rest while the above windows are still open.

Can you provide more details on how you are calling Chart.Line? E.g. in the REPL, via FSLab, in winforms, in wpf?
The following doesn't block for me when working in an fsx file. The other way would be to wrap it in an async block, which is useful if you're doing some long-running computation or accessing a database.
#load #"..\..\FSLAB\packages\FsLab\FsLab.fsx"
open Deedle
open FSharp.Charting
open System
let rnd = System.Random()
let xs = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
let xs' = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
Chart.Line(xs) // |> Chart.Show
Chart.Line(xs') //|> Chart.Show
Add:
async {Chart.Line(xs) |> Chart.Show } |> Async.Start
async {Chart.Line(xs') |> Chart.Show } |> Async.Start
MS Docs and F# Fun&Profit
Compiled example:
open System
open FSharp.Charting
open System.Threading
open System.Threading.Tasks
open System.Drawing
open FSharp.Charting
open FSharp.Charting.ChartTypes
[<STAThread>]
[<EntryPoint>]
let main argv =
let rnd = System.Random()
let xs = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
let xs' = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
Chart.Line(xs) |> Chart.Show
printfn "%A" "Chart 1"
Chart.Line(xs') |> Chart.Show
printfn "%A" "Chart 2"
async {Chart.Line(xs) |> Chart.Show } |> Async.Start
printfn "%A" "Chart 3"
async {Chart.Line(xs') |> Chart.Show } |> Async.Start
printfn "%A" "Chart 4"
Console.Read() |> ignore
printfn "%A" argv
0 // return an integer exit code

Related

F# async equivalent of Promise.race?

In JavaScript, there is a function called Promise.race that takes a list of promises and returns a new promise that completes when any of the input promises completes.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
F# has Async.Parallel, which completes when all of the input asyncs have completed, but it does not seem to have an equivalent for any (such as Async.Race).
How can I write this in F#?
You could use tasks.
Something like this:
let race xs =
xs
|> Seq.map Async.StartAsTask
|> Task.WhenAny
|> Async.AwaitTask
Using Async.Choice from FSharp.Control:
let race xs =
async {
let! first =
xs
|> Seq.map (fun task -> async {
let! x = task
return Some x
})
|> Async.Choice
return Option.get first
}

F# ASync.Parallel plus main thread

I have an F# program to copy files that I want to work asynchronously. So far I have:
let asyncFileCopy (source, target, overwrite) =
let copyfn (source,target,overwrite) =
printfn "Copying %s to %s" source target
File.Copy(source, target, overwrite)
printfn "Copyied %s to %s" source target
let fn = new Func<string * string * bool, unit>(copyfn)
Async.FromBeginEnd((source, target, overwrite), fn.BeginInvoke, fn.EndInvoke)
[<EntryPoint>]
let main argv =
let copyfile1 = asyncFileCopy("file1", "file2", true)
let copyfile2 = asyncFileCopy("file3", "file4", true)
let asynctask =
[copyfile1; copyfile2]
|> Async.Parallel
printfn "doing other stuff"
Async.RunSynchronously asynctask |> ignore
which works (the files are copied) but not in the way I want. I want to start the parallel copy operations so that they begin copying. Meanwhile, I want to continue doing stuff on the main thread. Later, I want to wait for the asynchronous tasks to complete. What my code seems to do is set up the parallel copies, then do other stuff, but not actually execute the copies until it hits Async.Runsychronously.
Is there a way to, in effect, Async.Run"a"synchronously, to get the copies started in the thread pool, then do other stuff and later wait for the copies to finish?
Figured it out:
let asynctask =
[copyfile1; copyfile2]
|> Async.Parallel
|> Async.StartAsTask
let result = Async.AwaitIAsyncResult asynctask
printfn "doing other stuff"
Async.RunSynchronously result |> ignore
printfn "Done"
The key is using StartAsTask, AwaitIAsyncResult and only later RunSynchronously to await task completion

f# perform await async methods in list.iteri

I have the following code in F# 4.0
let processEscalation escalationAction (escalationEvents:UpdateCmd.Record list) =
printf "%A" Environment.NewLine
printf "Started %A" escalationAction
escalationEvents
|> List.iter ( fun x ->
printf "%A" Environment.NewLine
printf "escalation %A for with action: %A" x.incident_id escalationAction
service.PostAction(new Models.Action(x.incident_id, escalationAction, "escalated"))
|> Async.AwaitTask
|> ignore)
let ComposeEscalation() =
let escalationlevels = ["ESC1 REACHED"; "ESC2 REACHED"; "ESC3 REACHED"]
escalationlevels
|> List.map getEscalationEvents
|> List.iteri (fun i x -> processEscalation escalationlevels.[i] x)
where the following line is a call to a C# async method that that returns Task
service.PostAction(new Models.Action(x.incident_id, escalationAction, "escalated"))
The compose escalation method calls the processEscalation three times.
However, the second call starts before the first call is complete.
How can I make sure that the the last line, list.iteri awaits and processes them sequentially?
Perhaps the processEscalation should be in an async computation expression?
What Async.AwaitTask does is that it returns an Async computation that can be used to wait for the task to complete. In your case, you never do anything with it, so the loop just proceeds to the next iteration.
You want something like this:
service.PostAction(new Models.Action(x.incident_id, escalationAction, "escalated"))
|> Async.AwaitTask
|> Async.RunSynchronously
|> ignore
This should have the effect you expect, though certainly there are nicer, more composable ways of expressing such logic.
Edit: What I meant was something like this, a counterpart to the core Async.Parallel function:
module Async =
let sequential (asyncs: seq<Async<'t>>) : Async<'t []> =
let rec loop acc remaining =
async {
match remaining with
| [] -> return Array.ofList (List.rev acc)
| x::xs ->
let! res = x
return! loop (res::acc) xs
}
loop [] (List.ofSeq asyncs)
Then you can do something along these lines:
escalationEvents
// a collection of asyncs - note that the task won't start until the async is ran
|> List.map (fun x ->
async {
let task =
service.PostAction(new Models.Action(x.incident_id, escalationAction, "escalated"))
return! Async.AwaitTask task
})
// go from a collection of asyncs into an async of a collection
|> Async.sequential
// you don't care about the result, so ignore it
|> Async.Ignore
// now that you have your async, you need to run it in a way that makes sense
// in your context - Async.Start could be another option.
|> Async.RunSynchronously
The upside here is that instead of bundling everything into a single loop, you've split the computation into well-delimited stages. It's easy to follow and refactor (e.g. if you need to process those events in parallel instead, you just switch out one step in the pipeline).

Akka.net F# stateful actor that awaits multipe FileSystemWatcher Observable events

I'm new to F# as well as Akka.Net and trying to achieve the following with them:
I want to create an actor (Tail) that receives a file location and then listens for events at that location using FileSystemWatcher and some Observables, forwarding them on as messages to some other actor for processing.
The problem I'm having is that the code to listen for the events only picks up one event at a time and ignores all the others. e.g. if I copy 20 files into the directory being watched it only seems to send out the event for 1 of them.
Here's my Actor code:
module Tail
open Akka
open Akka.FSharp
open Akka.Actor
open System
open Model
open ObserveFiles
open ConsoleWriteActor
let handleTailMessages tm =
match tm with
| StartTail (f,r) ->
observeFile f consoleWriteActor |!> consoleWriteActor
|> ignore
let spawnTail =
fun (a : Actor<IMessage> ) ->
let rec l (count : int) = actor{
let! m = a.Receive()
handleTailMessages m
return! l (count + 1)
}
l(0)
and here's the code that listens for events:
module ObserveFiles
open System
open System.IO
open System.Threading
open Model
open Utils
open Akka
open Akka.FSharp
open Akka.Actor
let rec observeFile (absolutePath : string) (a : IActorRef ) = async{
let fsw = new FileSystemWatcher(
Path = Path.GetDirectoryName(absolutePath),
Filter = "*.*",
EnableRaisingEvents = true,
NotifyFilter = (NotifyFilters.FileName ||| NotifyFilters.LastWrite ||| NotifyFilters.LastAccess ||| NotifyFilters.CreationTime ||| NotifyFilters.DirectoryName)
)
let prepareMessage (args: EventArgs) =
let text =
match box args with
| :? FileSystemEventArgs as fsa ->
match fsa.ChangeType with
| WatcherChangeTypes.Changed -> "Changed " + fsa.Name
| WatcherChangeTypes.Created -> "Created " + fsa.Name
| WatcherChangeTypes.Deleted -> "Deleted " + fsa.Name
| WatcherChangeTypes.Renamed -> "Renamed " + fsa.Name
| _ -> "Some other change " + fsa.ChangeType.ToString()
| :? ErrorEventArgs as ea -> "Error: " + ea.GetException().Message
| o -> "some other unexpected event occurd" + o.GetType().ToString()
WriteMessage text
let sendMessage x = async{ async.Return(prepareMessage x) |!> a
return! observeFile absolutePath a }
let! occurance =
[
fsw.Changed |> Observable.map(fun x -> sendMessage (x :> EventArgs));
fsw.Created |> Observable.map(fun x -> sendMessage (x :> EventArgs));
fsw.Deleted |> Observable.map(fun x -> sendMessage (x :> EventArgs));
fsw.Renamed |> Observable.map(fun x -> sendMessage (x :> EventArgs));
fsw.Error |> Observable.map(fun x -> sendMessage (x :> EventArgs));
]
|> List.reduce Observable.merge
|> Async.AwaitObservable
return! occurance
}
It took quite a few hacks to get it to this point, any advice on how I could change it, so that it picks up and processes all the events while the actor is running would be greatly appreciated.
When designing task like that, we could split it into following components:
Create manager responsible for receiving all messages - it's main role is to respond on incoming directory listening requests. Once request comes in, it creates a child actor responsible for listening under this specific directory.
Child actor is responsible for managing FileSystemWatcher for specific path. It should subscribe to incoming events and redirect them as messages to actor responsible for receiving change events. It should also free disposable resources when it's closed.
Actor responsible for receiving change events - in our case by displaying them on the console.
Example code:
open Akka.FSharp
open System
open System.IO
let system = System.create "observer-system" <| Configuration.defaultConfig()
let observer filePath consoleWriter (mailbox: Actor<_>) =
let fsw = new FileSystemWatcher(
Path = filePath,
Filter = "*.*",
EnableRaisingEvents = true,
NotifyFilter = (NotifyFilters.FileName ||| NotifyFilters.LastWrite ||| NotifyFilters.LastAccess ||| NotifyFilters.CreationTime ||| NotifyFilters.DirectoryName)
)
// subscribe to all incoming events - send them to consoleWriter
let subscription =
[fsw.Changed |> Observable.map(fun x -> x.Name + " " + x.ChangeType.ToString());
fsw.Created |> Observable.map(fun x -> x.Name + " " + x.ChangeType.ToString());
fsw.Deleted |> Observable.map(fun x -> x.Name + " " + x.ChangeType.ToString());
fsw.Renamed |> Observable.map(fun x -> x.Name + " " + x.ChangeType.ToString());]
|> List.reduce Observable.merge
|> Observable.subscribe(fun x -> consoleWriter <! x)
// don't forget to free resources at the end
mailbox.Defer <| fun () ->
subscription.Dispose()
fsw.Dispose()
let rec loop () = actor {
let! msg = mailbox.Receive()
return! loop()
}
loop ()
// create actor responsible for printing messages
let writer = spawn system "console-writer" <| actorOf (printfn "%A")
// create manager responsible for serving listeners for provided paths
let manager = spawn system "manager" <| actorOf2 (fun mailbox filePath ->
spawn mailbox ("observer-" + Uri.EscapeDataString(filePath)) (observer filePath writer) |> ignore)
manager <! "testDir"

custom async primitive function in f# using Async.FromContinuations

I'm a bit newbie with the async workflow and I think it has somethings I am not understand so well...I'm following the book Real world functional programming and in it writes the async primitive in this way
let Sleep(time) =
Async.FromContinuations(fun (cont, econt, ccont) ->
let tmr = new System.Timers.Timer(time, AutoReset = false)
tmr.Elapsed.Add(fun _ -> cont())
tmr.Start()
);;
I've tried write my own async primitive using a very slow factorial implementation, the code is it:
let rec factorial(n : int) (mem : bigint) =
match n with
| 0 | 1 -> printfn "%A" mem
| _ -> factorial (n - 1) (mem * bigint(n))
let BigFactorial(numero,mesaje)=
Async.FromContinuations(fun (cont,error,cancelation) ->
printfn "begin number: %s" mesaje
factorial numero 1I |>ignore
printfn "End number: %s ." mesaje
cont())
now I wrote this
Async.RunSynchronously(async{
printfn "Start!!..."
do! BigFactorial(30000,"30M")
do! BigFactorial(10000, "10M")
printfn "End!!..."
})
but it isn't running in async way precisely....
Start!!...
begin number: 30M
2759537246219...(A nice long number!)
end number: 30M .
begin number: 10M .
2846259680917054518906...(other nice number)
End!!...
if I execute it in parallel then works good...
let task1 = async{
printfn "begin"
do! BigFactorial(30000,"30")
printfn "end..."
}
let task2 = async{
printfn "begin"
do! BigFactorial(10000,"10")
printfn "end!!..."
}
Async.RunSynchronously(Async.Parallel[task1;task2])
begin
begin: 30
begin
begin: 10M
//long numbers here
end....
end.....
but I wish know the reason (or the several reasons!) why the first code doesn't work...
thanks so much I appreciate any help...
As with all async bindings, do! runs on the current thread, and thus your two sequential do!s run sequentially.
If you want them to run in parallel, you must say so explicitly:
async {
printfn "Start!!..."
let! tokenA = BigFactorial (30000, "30M") |> Async.StartChild // on new thread
let! tokenB = BigFactorial (10000, "10M") |> Async.StartChild // on new thread
do! tokenA // block until `BigFactorial (30000, "30M")` finishes
do! tokenB // block until `BigFactorial (10000, "10M")` finishes
printfn "End!!..." }
|> Async.RunSynchronously

Resources