2015-02-06 95 views
3

我正在努力编写一个F#代码,它将按顺序等待一些异步方法调用。我熟悉F#异步工作流程,但无法弄清楚如何映射到一个简单的案例。什么是使用异步的C#代码的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; 
     } 
    } 
} 

如果这个代码没有使用异步调用,我们可以只使用递归和模式匹配重写它在F#。但是它使用ReadAsync和GetValueAsync,它们如何用F#对应表达?

+0

为什么不只是使用递归?我没有看到任何会阻止它的东西 – mydogisbox 2015-02-06 17:12:37

+0

AC#到F#的转换(做得不好)在这里:https://github.com/xamarin/xamarin-store-app/blob/master/Shared/Data/WebService.cs https ://github.com/xamarin/shirt-store-fsharp/blob/master/Shared/WebService.fs – mydogisbox 2015-02-06 17:14:44

回答

5

这是完全没有经过测试的,但我认为这一点很重要。其实质是,你需要使用Async.AwaitTaskTask转换为Async,然后其余部分非常明显。

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 
+0

非常感谢!这正是我想要实现的。我在尝试编写类似的代码时错过了Async.AwaitTask。 – 2015-02-06 17:52:29

+0

请注意这里的异步帮助函数:https://github.com/xamarin/shirt-store-fsharp/blob/master/Shared/Helpers.fs – mydogisbox 2015-02-06 17:53:32

+0

哦,这是非常有益的,再次感谢! – 2015-02-06 18:54:53

相关问题