Asynchronous F#使用可变对象异步逐行读取csv

Asynchronous F#使用可变对象异步逐行读取csv,asynchronous,f#,mutable,Asynchronous,F#,Mutable,我在这里读了很多帖子,这些帖子对我的问题帮助很大,但我所有的尝试都没有结果 这是我的密码: 第一个功能(逐行读取文件以供使用) 第二个功能(处理行) 编辑:输入错误我在第一篇文章中忘记了字符串行 let processLine (line:string) (myobj:MYOBJ) = // .... some processing myobj // I return the object modified 现在我想用这个异步处理文件(尝试不起作用!但目的是解释我希望它做什么) 我试着使

我在这里读了很多帖子,这些帖子对我的问题帮助很大,但我所有的尝试都没有结果

这是我的密码:

第一个功能(逐行读取文件以供使用)

第二个功能(处理行) 编辑:输入错误我在第一篇文章中忘记了字符串行

let processLine (line:string) (myobj:MYOBJ) = 
// ....  some processing
myobj  // I return the object modified
现在我想用这个异步处理文件(尝试不起作用!但目的是解释我希望它做什么)

我试着使用ref和!但没有拿出一个干净清晰的解决方案。 在这种情况下,最好的代码实践是什么

可能的解决办法: 感谢您的宝贵帮助,这里有两种可能的解决方案

第一种解决方案:

let readL (file:string) = 
async {
        let mutable myobj = ref(new MYOBJ())
        use sr = new StreamReader(file)
        while not sr.EndOfStream do
            let line = sr.ReadLine()
            myobj := proccesLine line !myobj
            ()
        sr.Close()
        }
第二种解决方案:(使用CSVReader库)

现在,我仍然想知道,在使用Seq.iter时,是否有可能有一个内联函数返回除单元类型以外的内容。代码将更容易阅读

编辑:iljarn提出的解决问题的第三个解决方案

let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold processLine }

这似乎是一个合适的用例:

请注意,如果颠倒
processLine
参数的顺序,则可以将其减少为:

let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold processLine }

你的问题毫无意义——你说
processLine
接受一个
MYOBJ
,但实际上你是在传递一个
字符串,在这种情况下,你的代码相当于
让obj=readLines file |>Seq.last |>processLine
。在任何情况下,根据您对所需内容的描述,
ref
是最佳选择;显示您使用
ref
的尝试,它可能是可以纠正的。为什么您认为这会从异步中受益?@ildjarn:thx对于注释,我忘了在函数中添加字符串参数。也许我不够清楚:我必须通过阅读每一行来处理文件,并在转到下一行之前修改myobj。基本上,我发现我的问题相当于询问是否有可能有一个内联函数在Seq之后返回除unit以外的内容。iter@Daniel,我想异步使用这段代码,这就是为什么我指定了万一有任何可能的副作用,这正是我需要的,正如您可能已经注意到的,我仍然是一个F#新手,但我确实是,但语言的清晰和简单的语法吸引了我。我将编辑我的帖子来添加这一点,这样它可以帮助其他人通过不同的实现来解决这个问题,而不是编辑的第一个解决方案中的代码不起作用–
让myobj=proccesLine myobj
隐藏之前的
myobj
,而不是对其进行变异。您需要
让myobj=ref(myobj())
myobj:=proccesLine!myobj
let readL (file:string) =
async {
        let myobj = new MYOBJ()
        use sr = new CsvReader(new StreamReader(file),false)
        let fcount = sr.FieldCount
        let data : string array = Array.zeroCreate fcount
        let rec readLinloop (readNext, str:CsvReader, obj:MYOBJ) = 
            match readNext with
                | false -> ()
                | true -> sr.CopyCurrentRecordPartTo(data,0)
                          let obj = processLine data obj
                          readL(str.ReadNextRecord(), str, obj)
        readLinLoop(sr.ReadNextRecord(),sr, myobj)
        sr.Dispose()
        }
let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold processLine }
let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold (fun o l -> processLine l o) }
let processAll file =
    async { (MYOBJ(), readLines file) ||> Seq.fold processLine }