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 }