Async Global Status and Workflows in F #

A common example used to illustrate asynchronous workflows in F # is to get multiple web pages at once. One such example is shown below: http://en.wikibooks.org/wiki/F_Sharp_Programming/Async_Workflows The code is shown here if the link changes in the future:

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()

What I would like to know is how to handle changes in the global state, such as losing a network connection? Is there an elegant way to do this?

You can check the network status before making an asynchronous call, but the status can change at run time. Assuming what needs to be done is to pause execution until the network is accessible again and not working, is there any way to do this?

+5
1

, : Async.Parallel , , .

. , download downloadAndExtractLinks , AsyncDownloadString WebClient:

let asyncDownload url = async {
    let webclient = new System.Net.WebClient()
    return! webclient.AsyncDownloadString(System.Uri(url : string)) }

let asyncDownloadAndExtractLinks url = async {
    let! html = asyncDownload url
    let links = extractLinks html
    return url, links.Count }

let pmap f l =
    seq { for a in l -> async { return! f a } }
    |> Async.Parallel
    |> Async.RunSynchronously

. , - , , . . - , , . 10 . , :

let rec asyncRetry times op = async {
  try
    return! op
  with e ->
    if times <= 1 then return (reraise e)
    else return! asyncRetry (times - 1) op }

, 10 :

let testAsynchronous() = 
  pmap (asyncRetry 10 downloadAndExtractLinks) urls

. , Async.Parallel ( -, ). , .

- F # - , , - , , - . , , async (, , ).

MSDN , two developerFusion, F #.

+4

All Articles