Click here to Skip to main content
13,900,697 members
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

1.8K views
Posted 6 Mar 2019
Licenced CPOL

Ignoring Operation Result when using F# async Computation Expression

, 6 Mar 2019
Rate this:
Please Sign up or sign in to vote.
Simple pitfall where C# developers trying out F# might fail when writing async code

Using the Code

Consider this simple code downloading page contents using Puppeteer-sharp.

let renderHtml = async {
    BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision) |> Async.AwaitTask |> ignore
    let options = LaunchOptions()
    options.Headless <- true
    let! browser = Puppeteer.LaunchAsync(options) |> Async.AwaitTask
    let! page = browser.NewPageAsync() |> Async.AwaitTask
    page.GoToAsync("https://i.ua") |> Async.AwaitTask |> ignore    
    return! page.GetContentAsync() |> Async.AwaitTask    
}

Since we actually don't care about download browser result, we naturally would expect that our line...

BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision) |> Async.AwaitTask |> ignore

...would be equivalent to this C# code:

await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);

However, when we execute the following method, we get Aggregate<wbr />Exception which in turn contains the following inner exception: "Chromium revision is not downloaded. Run BrowserFetcher.DownloadAsync or download Chromium manually". Seems like we've called...

let! browser = Puppeteer.LaunchAsync(options) |> Async.AwaitTask

...without waiting for BrowserFetcher result.

And indeed, in order to await async call, we have to use let! construct. The code below works as expected:

let renderHtml = async {
    let! _ = BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision) |> Async.AwaitTask
    let options = LaunchOptions()
    options.Headless <- true
    let! browser = Puppeteer.LaunchAsync(options) |> Async.AwaitTask
    let! page = browser.NewPageAsync() |> Async.AwaitTask
    let! _ = page.GoToAsync("https://i.ua") |> Async.AwaitTask    
    return! page.GetContentAsync() |> Async.AwaitTask    
}

Note how we use underscore to show that the variable value is ignored.

History

  • 6th March, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bohdan Stupak
Software Developer
Ukraine Ukraine
https://twitter.com/BohdanStupak1

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionUse `do!` instead of `let! _ =` Pin
Sergey Tihon8-Mar-19 21:17
memberSergey Tihon8-Mar-19 21:17 
AnswerRe: Use `do!` instead of `let! _ =` Pin
Bohdan Stupak14-Mar-19 23:23
professionalBohdan Stupak14-Mar-19 23:23 
QuestionYep Pin
Sacha Barber8-Mar-19 20:25
mvaSacha Barber8-Mar-19 20:25 
AnswerRe: Yep Pin
Bohdan Stupak14-Mar-19 23:19
professionalBohdan Stupak14-Mar-19 23:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190306.1 | Last Updated 6 Mar 2019
Article Copyright 2019 by Bohdan Stupak
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid