Concurrency 在OCaml中使用Lwt时如何使循环中断

Concurrency 在OCaml中使用Lwt时如何使循环中断,concurrency,ocaml,ocaml-lwt,Concurrency,Ocaml,Ocaml Lwt,我正在编写代码来监视文件的内容。当程序到达文件的末尾时,我希望它干净地终止 let log () : input_channel Lwt.t = openfile "log" [O_RDONLY] 0 >>= fun fd -> Lwt.return (of_fd input fd);; let rec loop (ic: input_channel) = Lwt_io.read_line ic >>= fun text -> Lwt_

我正在编写代码来监视文件的内容。当程序到达文件的末尾时,我希望它干净地终止

let log () : input_channel Lwt.t = 
  openfile "log" [O_RDONLY] 0 >>= fun fd -> 
  Lwt.return (of_fd input fd);;

let rec loop (ic: input_channel) = Lwt_io.read_line ic >>= fun text -> 
    Lwt_io.printl text >>= fun _ -> loop ic;;

let monitor () : unit Lwt.t = log () >>= loop;;

let handler : exn -> unit Lwt.t = fun e -> match e with
    | End_of_file -> let (p: unit Lwt.t), r = Lwt.wait() in p
    | x -> Lwt.fail x;;

let main () : unit Lwt.t = Lwt.catch monitor handler;;

let _ = Lwt_main.run (main ());;
但是,当读取文件并到达结尾时,程序不会终止,它只是挂起,我必须使用Ctrl+c进行转义。我不确定bind的引擎盖下到底发生了什么,但我认为无论它在做什么,最终
Lwt\u io.readline ic
都会到达文件的末尾,并返回
end\u of\u file
异常,这可能会传递给处理程序,等等


如果我不得不猜测一个解决方案,我会想也许在
>=
定义的最后一个绑定中,我会包含一些
If
检查。但我想我会检查
Lwt\u io.read\u line
是否返回了
End\u文件
,我认为这应该由
处理程序处理

Lwt.wait
函数创建一个只能使用返回对的第二个元素解析的承诺,基本上,此函数永远不会终止:

let never_ready () = 
  let (p,_) = Lwt.wait in
  p
这正是你写的

理想情况下,关于优雅终止,您应该在
循环
功能中执行此操作,以便关闭通道并防止宝贵资源泄漏,例如

let rec loop (ic: input_channel) = 
  Lwt_io.read_line ic >>= function
  | exception End_of_file -> 
    Lwt.close ic
  | text->
    Lwt_io.printl text >>= fun () -> 
    loop ic

但是,对代码的最小更改是使用
Lwt.return()
而不是
Lwt.wait
处理程序的主体中

我对Lwt知之甚少,但是从对代码的简单阅读来看,我并不奇怪它会挂起,因为在文件的
末尾
调用
等待
然后扔掉解析器。所以它当然会等待。。。。您为什么不在这里使用
return()