> `let private WaitForData (client : TcpClient, dataLength : int) : Async<bool>=` > `let mutable loopBreaker : bool = true` > > `let isConnectionAlive : bool = IsConnectionEstablished client && client <> null` You should only use explicit type declaration when the compiler demands it: `let private WaitForData (client : TcpClient) dataLength =` `let mutable loopBreaker = true` `let isConnectionAlive = IsConnectionEstablished client && client <> null` ---------- > `let isConnectionAlive : bool = IsConnectionEstablished client && client <> null` It seems rather risky to me that you use `client` in a function call before testing it for null. I would do it in reverse order: let isConnectionAlive = client <> null && IsConnectionEstablished client But why evaluate the `client` for `null` in the loop in the first place? You should return false immediately if it's `null`. ---------- > Task.Delay(500) |> Async.AwaitTask |> ignore I don't think this is actually waiting 500 ms as you may expect. Instead you can do: do! Async.Sleep 500 or do! Task.Delay(500) |> Async.AwaitTask ---------- As Bohdan stupak shows you can do the same in a recursive fashion like: let private waitForData (client: TcpClient) dataLength = let rec waiter () = async { if client = null then return false else match isConnected client, client.Available >= dataLength with | true, true -> return true | true, false -> do! Async.Sleep 500 return! waiter () | false, dataFound -> return dataFound } waiter()