Typowym przykładem ilustrującym asynchroniczne przepływy pracy w F # jest pobieranie wielu stron jednocześnie. Jednym z takich przykładów jest podana na stronie: http://en.wikibooks.org/wiki/F_Sharp_Programming/Async_Workflows kod pokazany tutaj w przypadku zmiany ogniwem w przyszłości:Globalny stan i asynchroniczne przepływy pracy w języku 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()
Co chciałbym wiedzieć, jak należy obsługiwać zmiany stanu globalnej, takich jak utrata połączenia sieciowego? Czy istnieje elegancki sposób na zrobienie tego?
Można sprawdzić stan sieci przed wykonaniem połączenia Async.Parallel, ale stan może się zmienić podczas wykonywania. Zakładając, że ktoś chciał zrobić, to wstrzymać wykonywanie, dopóki sieć nie będzie dostępna, a nie zawiedzie, czy istnieje funkcjonalny sposób, aby to zrobić?
Tom, chociaż bardzo lubię agentów F #, nie widzę, jak to jest programowanie funkcjonalne, takie jak Haskell. To, co wydaje się robić, to raczej traktowanie stanu (IO Monad w Haskell) jako czegoś, co ma zostać przekazane do funkcji, traktuje stan jako coś, co musi zostać zmutowane przez wielu agentów "jednocześnie" i rozstrzygnięte z komunikatem przekazywanym między agentami. – JonnyBoats
Używanie agentów zdecydowanie nie działa tak jak Haskell.Szczerze mówiąc nie sądzę, że czysto funkcjonalne rozwiązania tego problemu są tak eleganckie i użyteczne. Współbieżność przekazywania komunikatów jest kolejnym przydatnym paradygmatem, który jest dostępny w języku F # - i myślę, że działa on bardzo dobrze dla współbieżnych procesów, które muszą koordynować. –
To jest coś, co próbuję w tej chwili objąć. Po odkryciu FP przez takich jak Haskell (ale wciąż bardzo niedoświadczonych w tym), pokusą jest, aby przejść do całkowicie czystego podejścia w F #, too. Znalezienie odpowiedniej mieszanki paradygmatów będzie, jak sądzę, długim procesem uczenia się. – shambulator