Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何使此函数正确地异步?_F# - Fatal编程技术网

F# 如何使此函数正确地异步?

F# 如何使此函数正确地异步?,f#,F#,我试图让F#async工作,但我就是不知道我做错了什么。下面是我运行的一些同步代码: open System.Net open System.Runtime.Serialization open System.Threading.Tasks [<DataContract>] type Person = { [<field: DataMember(Name = "name")>] Name : string [<field: DataMemb

我试图让F#async工作,但我就是不知道我做错了什么。下面是我运行的一些同步代码:

open System.Net
open System.Runtime.Serialization
open System.Threading.Tasks

[<DataContract>]
type Person = {
    [<field: DataMember(Name = "name")>]
    Name : string
    [<field: DataMember(Name = "phone")>]
    Phone : int
}

let url = "http://localhost:5000/app/plugins/anon/CCure"
let js  = Json.DataContractJsonSerializer(typeof<Person>)

let main x =
   let client = new WebClient()
   let url = url + "/" + x
   let reader = client.OpenRead(url)
   let person = js.ReadObject(reader) :?> Person

   printfn "Name: %s, Phone number: %d" person.Name person.Phone

printfn "starting x"
let x = Task.Factory.StartNew(fun () -> main "x")
printfn "starting y"
let y = Task.Factory.StartNew(fun () -> main "y")
Task.WaitAll(x, y)
开放系统.Net
open System.Runtime.Serialization
开放系统.Threading.Tasks
[]
类型人={
[]
名称:string
[]
电话:int
}
让url=”http://localhost:5000/app/plugins/anon/CCure"
让js=Json.DataContractJsonSerializer(typeof)
让main x=
let client=new WebClient()
设url=url+“/”+x
让reader=client.OpenRead(url)
让person=js.ReadObject(reader):?>person
printfn“姓名:%s,电话号码:%d”person.Name person.Phone
打印fn“开始x”
设x=Task.Factory.StartNew(fun()->main“x”)
打印fn“开始y”
让y=Task.Factory.StartNew(fun()->main“y”)
Task.WaitAll(x,y)
我认为异步运行它会起作用,但它不能:

open System.Net
open System.Runtime.Serialization
open System.Threading.Tasks

[<DataContract>]
type Person = {
    [<field: DataMember(Name = "name")>]
    Name : string
    [<field: DataMember(Name = "phone")>]
    Phone : int
}

let url = "http://localhost:5000/app/plugins/anon/CCure"
let js  = Json.DataContractJsonSerializer(typeof<Person>)

let main x = async {
   let client = new WebClient()
   let url = url + "/" + x
   let! reader = client.OpenReadAsync(url)
   let person = js.ReadObject(reader) :?> Person

   printfn "Name: %s, Phone number: %d" person.Name person.Phone }

printfn "starting x"
let x = Task.Factory.StartNew(fun () -> main "x")
printfn "starting y"
let y = Task.Factory.StartNew(fun () -> main "y")
Task.WaitAll(x, y)
开放系统.Net
open System.Runtime.Serialization
开放系统.Threading.Tasks
[]
类型人={
[]
名称:string
[]
电话:int
}
让url=”http://localhost:5000/app/plugins/anon/CCure"
让js=Json.DataContractJsonSerializer(typeof)
让main x=async{
let client=new WebClient()
设url=url+“/”+x
let!reader=client.OpenReadAsync(url)
让person=js.ReadObject(reader):?>person
printfn“姓名:%s,电话号码:%d”person.Name person.Phone}
打印fn“开始x”
设x=Task.Factory.StartNew(fun()->main“x”)
打印fn“开始y”
让y=Task.Factory.StartNew(fun()->main“y”)
Task.WaitAll(x,y)
$fsharpc-r System.Runtime.foo.fs&&./foo.exe F# F#3.1(开源版)编译器在 Apache 2.0开放源代码许可证

/home/frew/code/foo.fs(19,18):错误FS0001:此表达式无效 期望有类型
Async
OpenReadAsync
是.NET BCL的一部分,因此设计时没有考虑F#Async。您会注意到它返回的是
unit
,而不是
Async
,因此它不能与let!一起工作

API设计用于事件(即,您必须连接
客户端.OpenReadCompleted

你有几个选择

  • FSharp.Core
    中有一些很好的助手方法可以提供帮助 您需要将API转换为更友好的API(请参见
    Async.AwaitEvent
  • 使用
    AsyncDownloadString
    ,这是一种WebClient的扩展方法,可以在
    Microsoft.FSharp.Control.WebExtensions
    中找到。这更容易,所以我在下面做了,虽然这确实意味着将整个流作为字符串保存在内存中,所以如果您有大量Json,这可能不是最好的主意
  • 使用异步而不是任务来并行运行更为惯用

    open System.Net
    open System.Runtime.Serialization
    open System.Threading.Tasks
    open Microsoft.FSharp.Control.WebExtensions
    open System.Runtime.Serialization.Json
    
    [<DataContract>]
    type Person = {
        [<field: DataMember(Name = "name")>]
        Name : string
        [<field: DataMember(Name = "phone")>]
        Phone : int
    }
    
    let url = "http://localhost:5000/app/plugins/anon/CCure"
    let js  = Json.DataContractJsonSerializer(typeof<Person>)
    
    
    let main x = async {
       printfn "Starting %s" x
       let client = new WebClient()
       let url = url + "/" + x
       let! json = client.AsyncDownloadString(System.Uri(url))
       let bytes = System.Text.Encoding.UTF8.GetBytes(json)
       let st = new System.IO.MemoryStream(bytes)
       let person = js.ReadObject(st) :?> Person
    
       printfn "Name: %s, Phone number: %d" person.Name person.Phone }
    
    
    let x = main "x"
    let y = main "y"
    
    [x;y] |> Async.Parallel |> Async.RunSynchronously |> ignore<unit[]>
    
    开放系统.Net
    open System.Runtime.Serialization
    开放系统.Threading.Tasks
    打开Microsoft.FSharp.Control.WebExtensions
    open System.Runtime.Serialization.Json
    []
    类型人={
    []
    名称:string
    []
    电话:int
    }
    让url=”http://localhost:5000/app/plugins/anon/CCure"
    让js=Json.DataContractJsonSerializer(typeof)
    让main x=async{
    打印fn“开始%s”x
    let client=new WebClient()
    设url=url+“/”+x
    让!json=client.AsyncDownloadString(System.Uri(url))
    让bytes=System.Text.Encoding.UTF8.GetBytes(json)
    设st=新系统.IO.MemoryStream(字节)
    让person=js.ReadObject(st):?>person
    printfn“姓名:%s,电话号码:%d”person.Name person.Phone}
    设x=主“x”
    设y=main“y”
    [x;y]|>异步.Parallel |>异步.RunSynchronously |>忽略
    
    我猜是主异步块中的
    printfn
    语句。也许添加
    person
    作为回报会有所帮助。这里似乎有些不正确。。。我从中得到这个异常:System.IO.FileNotFoundException:找不到文件“/home/frew/code/fsharp/{“name”:“john”,“phone”:12312}”。