2

我想这是一个经典的 C# 到 F# 的转换,我还没有完全理解。

我正在尝试使用快速启动自动化浏览器

https://playwright.dev/dotnet/docs/intro

C#代码是

using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.GotoAsync("http://www.bing.com");
await page.ScreenshotAsync(path: outputFile);

我已经开始了,但已经有点迷失了。

let playwright: Playwright = PlaywrightSharp.Playwright.CreateAsync() |> Async.AwaitTask

类型不正确。我在这里做错了什么?

Error   FS0001  This expression was expected to have type
    'Playwright'    
but here has type
    'Async<IPlaywright>'    
4

3 回答 3

1

您可以使用 TaskBuilder 框架https://github.com/rspeele/TaskBuilder.fs

dotnet 添加包 Taskbuilder.fs

和写

task {    
    use! playwright =  Playwright.CreateAsync() 
    let! browser =  playwright.Chromium.LaunchAsync()
    let! page = browser.NewPageAsync()
    
    let! response = page.GoToAsync("http://www.bing.com")
    let! title =  page.GetTitleAsync()

    printfn "%s" title

}
|> Task.WaitAll
于 2021-05-19T21:33:36.073 回答
1

一种方法是使用 F# 对异步计算表达式的内置支持。翻译看起来像这样:

let (~~) = Async.AwaitTask

async {
    use! playwright = ~~Playwright.CreateAsync()
    let! browser = ~~playwright.Chromium.LaunchAsync()
    let! page = ~~browser.NewPageAsync()
    do! ~~page.GoToAsync("http://www.slashdot.com") |> Async.Ignore
    do! ~~page.ScreenshotAsync(outputFile) |> Async.Ignore
} |> Async.RunSynchronously

这里有一些你需要知道的微妙之处:

  • F# 有自己的异步类型,称为Async<'T>. 我习惯于Async.AwaitTask从 C# 风格的任务转换,并定义了一个前缀运算符 ,~~以使其看起来更清晰。
  • F# 尚不支持计算表达式DisposeAsync,因此浏览器无法正确处理。如果需要,您可以在块的末尾添加手动执行此操作。asyncdo! browser.DisposeAsync().AsTask() |> Async.AwaitTask
  • F# 要求我们明确忽略不需要的返回值,我通过Async.Ignore.
于 2021-05-19T21:33:56.120 回答
1

从 F# 6 开始,现在通过任务计算表达式原生支持任务。语法几乎与 Brian Berns 答案中的异步计算表达式相同,只是您不再需要调用Async.AwaitTaskeach let!use!do!binding 。

let screenshotTask =
  task {
    use! playwright = Playwright.CreateAsync ()
    use! browser = playwright.Chromium.LaunchAsync ()
    let! page = browser.NewPageAsync ()
    let! _ = page.GotoAsync "https://www.bing.com"
    let! _ = page.ScreenshotAsync (PageScreenshotOptions(Path = "screenshot.png"))
    return ()
  }
screenshotTask.Wait ()
于 2022-01-06T12:55:08.600 回答