gpt4 book ai didi

asynchronous - F# 使用关键字和递归函数

转载 作者:行者123 更新时间:2023-12-01 11:36:04 24 4
gpt4 key购买 nike

据我所知,use 关键字一旦超出范围就会处理绑定(bind)的 IDisposable,所以考虑这个递归函数:

let rec AsyncAcceptMessages(client : WebSocket) =
async {
let! message = client.AsyncReadMessage
use reader = new StreamReader(message)
let s = reader.ReadToEnd()
printf "%s" <| s
do! AsyncAcceptMessages client
}

假设编译器没有找到使用尾递归的方法,StreamReader 会在每次递归后被释放吗?

更新

Tomas 的回复向我展示了一种在您实际期望得到返回时修复它的方法,但是如果您什么都不期望怎么办?就像这个使用 StreamWriter 的例子:

let rec AsyncAcceptMessages(client : WebSocket) =
async {
let! message = client.AsyncReadMessage
if(not(isNull message)) then
let s =
use reader = new StreamReader(message)
reader.ReadToEnd()
use writer = new StreamWriter(client.CreateMessageWriter(WebSocketMessageType.Text), Encoding.UTF8)
writer.Write s
printf "%s" <| s
do! AsyncAcceptMessages client
}

最佳答案

如您所说,StreamReader 只会在递归调用执行返回后 被释放(即永远不会)。

还有一个问题,就是do!没有被当作尾递归调用,所以如果你想创建一个无限尾递归循环,你需要使用 return!(否则您的代码将泄漏内存)。

在这种情况下,您可以轻松地修复它,因为您没有对 StreamReader 执行任何异步操作,所以您可以只创建一个普通的本地范围:

let rec AsyncAcceptMessages(client : WebSocket) =
async {
let! message = client.AsyncReadMessage
let s =
use reader = new StreamReader(message)
reader.ReadToEnd()
printf "%s" <| s
return! AsyncAcceptMessages client
}

如果您想调用AsyncReadToEnd,那么您可以执行如下操作:

let rec AsyncAcceptMessages(client : WebSocket) =
async {
let! message = client.AsyncReadMessage
let! s =
async { use reader = new StreamReader(message)
return! reader.ReadToEnd() }
printf "%s" <| s
return! AsyncAcceptMessages client
}

关于asynchronous - F# 使用关键字和递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26976175/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com