Un esempio comune utilizzato per illustrare flussi di lavoro asincroni in F # è il recupero di più pagine Web in parallelo. Un esempio è dato a: http://en.wikibooks.org/wiki/F_Sharp_Programming/Async_Workflows codice mostrato qui nel caso in cui i cambiamenti di collegamento per il futuro:Flussi di lavoro globali e asincroni in F #
open System.Text.RegularExpressions
open System.Net
let download url =
let webclient = new System.Net.WebClient()
webclient.DownloadString(url : string)
let extractLinks html = Regex.Matches(html, @"http://\S+")
let downloadAndExtractLinks url =
let links = (url |> download |> extractLinks)
url, links.Count
let urls =
[@"http://www.craigslist.com/";
@"http://www.msn.com/";
@"http://en.wikibooks.org/wiki/Main_Page";
@"http://www.wordpress.com/";
@"http://news.google.com/";]
let pmap f l =
seq { for a in l -> async { return f a } }
|> Async.Parallel
|> Async.Run
let testSynchronous() = List.map downloadAndExtractLinks urls
let testAsynchronous() = pmap downloadAndExtractLinks urls
let time msg f =
let stopwatch = System.Diagnostics.Stopwatch.StartNew()
let temp = f()
stopwatch.Stop()
printfn "(%f ms) %s: %A" stopwatch.Elapsed.TotalMilliseconds msg temp
let main() =
printfn "Start..."
time "Synchronous" testSynchronous
time "Asynchronous" testAsynchronous
printfn "Done."
main()
Quello che vorrei sapere è come si dovrebbe gestire cambiamenti di stato globale come la perdita di una connessione di rete? C'è un modo elegante per farlo?
Uno potrebbe verificare lo stato della rete prima di effettuare la chiamata Async.Parallel, ma lo stato potrebbe cambiare durante l'esecuzione. Supponendo che cosa si voleva fare era sospendere l'esecuzione fino a quando la rete era nuovamente disponibile piuttosto che fallire, c'è un modo funzionale per farlo?
Tom, anche se mi piacciono molto gli agenti di F #, non vedo come questa sia una programmazione funzionale come Haskell. Ciò che sembra fare è piuttosto che lo stato di trattamento (l'IO Monad in Haskell) come qualcosa da passare a una funzione, considera lo stato come qualcosa che deve essere mutato da più agenti "simultaneamente" e arbitrato con il passaggio di messaggi tra agenti. – JonnyBoats
L'utilizzo di agenti non è sicuramente una programmazione funzionale come Haskell.Onestamente non penso che le soluzioni puramente funzionali al problema siano così eleganti e utili. La concorrenza di passaggio dei messaggi è solo un altro paradigma utile disponibile in F # - e penso che funzioni molto bene per i processi concorrenti che devono coordinarsi. –
Questo è qualcosa che sto cercando di mettere alla prova in questo momento. Avendo scoperto FP attraverso il calibro di Haskell (ma ancora molto inesperto), la tentazione è di adottare un approccio completamente puro anche in F #. Trovare la giusta miscela di paradigmi sarà un lungo processo di apprendimento, penso. – shambulator