使用异步的C#代码的F#等价物是什么?

Vag*_*lov 3 f# c#-to-f# async-await

我正在努力编写一个F#代码,它会顺序等待一些异步方法调用.我熟悉F#异步工作流程,但无法弄清楚如何映射到一个简单的案例.

我们以异步XmlReader为例.以下是C#代码的外观:

using (XmlReader r = XmlReader.Create(new StringReader(input), new XmlReaderSettings() { Async = true }))
{
    while (await r.ReadAsync())
    {
        switch (r.NodeType)
        {
            case XmlNodeType.Element:
                Console.WriteLine(r.LocalName);
                break;

            case XmlNodeType.Text:
                Console.WriteLine(await r.GetValueAsync());
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果此代码不使用异步调用,我们可以使用递归和模式匹配在F#中重写它.但它使用ReadAsync和GetValueAsync,它们如何用F#对应表达?

N_A*_*N_A 6

这是完全未经测试的,但我认为可以解决这个问题.它的本质是你需要转换TaskAsync使用Async.AwaitTask然后其余部分是非常明显的.

let doRecursiveAsyncThing input = async {
    use r = XmlReader.Create(new StringReader(input), new XmlReaderSettings(Async = true ))
    let loop x = async {
        let! noteType = r.ReadAsync() |> Async.AwaitTask
        match noteType with
        | XmlNodeType.Element -> Console.WriteLine r.LocalName
                                 do! loop x
        | XmlNodeType.Text    -> let! value = r.GetValueAsync() |> Async.AwaitTask
                                 Console.WriteLine value
                                 do! loop x
        | _                   -> () }

    }
    do! loop r
Run Code Online (Sandbox Code Playgroud)