代码之家  ›  专栏  ›  技术社区  ›  Ðаn

使用F#的内置异步支持和*async()方法

  •  1
  • Ðаn  · 技术社区  · 16 年前

    Event-based Asynchronous Pattern 例如 网络客户端

    let Download(url : Uri) =
        let client = new WebClient()
        let html = client.DownloadString(url)
        html
    

    当我试图将此更改为使用“let!”时 异步的 block(如Soma最近的 post )

    let Download(url : Uri) =
        async {
        let client = new WebClient()
        let! html = client.DownloadStringAsync(url)
        return html }
    

    我收到一条错误消息:

    类型约束不匹配。类型单元与类型Async<不兼容a>类型“unit”与类型“Async<”不兼容a>'

    编辑:我想问一下使用*Async()方法的一般问题,WebClient只是一个简单的例子。微软 says “…您应该尽可能使用基于事件的异步模式[而不是BeginFoo()/EndFoo()]来公开异步功能…”因此我认为应该有一种简单的方法来使用F#中的任意*Async()方法。

    1 回复  |  直到 16 年前
        1
  •  5
  •   Juliet    16 年前

    这个 WebClient.DownloadStringAsync unit async 对象

    val webclient.AsyncDownloadString : uri -> Async{string} :

    let Download(url : Uri) =
        async {
        let client = new WebClient()
        client.Encoding <- Encoding.GetEncoding("utf-8")
        let! html = client.AsyncDownloadString(url)
        return html }
    

    Async* .


    [编辑以添加对评论的响应:]

    通常,.NET使用BeginFoo/EndFoo模式进行并发。如果类型正确,您可以使用 Async.BuildPrimitive beginMethod endMethod ,它将返回该方法的异步包装。

    Async.AwaitEvent 等待触发事件,或编写自己的循环以反复检查是否设置了bool。这是一个很好的例子 article on converting events to Async objects

    值得一提的是,如果你已经安装了F#,你还应该有源代码,让你了解F#团队如何实现他们的异步扩展。在我的机器上,相关文件位于:

    C:\Program Files\FSharp-1.9.6.16\source\fsppack\FSharp.PowerPack\AsyncOperations.fs