簡體   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