繁体   English   中英

F#中的F#连续循环

[英]F# Continuous loop in F#

我有一个套接字服务器,需要在接受客户端的循环上运行,所以我发现在函数编程中,使用了一个递归循环:

let awaitConnections (wsl:WebSocketListener) = 
    let rec loop ()=
        async { 
            let! ws = Async.AwaitTask (wsl.AcceptWebSocketAsync(cancellation.Token) )
            printfn "Connection from %s" (ws.RemoteEndpoint.Address.ToString())
            Async.Start <| awaitMessages ws
            do! loop()}
    loop()

通过执行以下操作调用此代码:

Async.Start <| awaitConnections listener

考虑到应用程序连续运行,我应该使用迭代方法吗? rec方法是否会创建嵌套执行堆栈?

另外,我想在循环结束后做一些事情,比如:

let awaitConnections (wsl:WebSocketListener) = 
    let rec loop ()=
        async { 
            let! ws = Async.AwaitTask (wsl.AcceptWebSocketAsync(cancellation.Token) )
            printfn "Connection from %s" (ws.RemoteEndpoint.Address.ToString())
            Async.Start <| awaitMessages ws
            do! loop()}
    loop()
    printf "The loop ended" // <-- this line

但是它无法编译,因为awaitConnections返回类型。 我怎么能这样做? 我这样做了吗?

你肯定是在正确的轨道上! 这是一个简单的示例,演示了您需要执行的操作:

// Loop that keeps running forever until an exception happens
let rec loop () = async {
  do! Async.Sleep(1000)
  printfn "Working"
  return! loop () }

// Call the loop in a try .. finally block to run some cleanup code at the end
let main () = async {
  try 
    do! loop () 
  finally 
    printfn "That's it!" }

// Start the work in the background and create a cancellation token
let cts = new System.Threading.CancellationTokenSource()
Async.Start(main (), cts.Token)
// To cancel it, just call: cts.Cancel()

一些要点:

  • 在无限循环结束后你无法真正运行代码(它是无限的!)但你可以使用try .. finally在块被取消时运行一些代码

  • 注意使用return! 用于递归循环更好 - 使用do! 造成内存泄漏。

  • 您可以使用取消令牌取消计算 - 只需在启动时传递令牌。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM