[英]F# Async Dispose
我写了这个小的Web侦听器模拟:
Agent.Start(fun (_ : MailboxProcessor<unit>) ->
let listener = new HttpListener()
listener.Prefixes.Add(addr)
listener.Start()
let rec respondOut() = async {
let! context = Async.FromBeginEnd(listener.BeginGetContext, listener.EndGetContext)
use s = context.Response.OutputStream
let wr = new StreamWriter(s)
use disp = { new IDisposable with
member x.Dispose() =
printfn "Disposing..."
wr.Dispose() }
wr.Write("Test")
return! respondOut()
}
respondOut()
)
我不明白为什么在每个循环上都没有在Disp上调用Dispose?
作为一个附带的问题,我正在做所有这一切,因为我想测试什么是响应Web服务中文本的正确行为。 我不确定是否应该这样做:
use s = Context.Response.OutputStream
use sw = new StreamWriter(s)
sw.Write("test")
要么
Context.Response.Write("Test")
Context.Response.End()
还是什么。
谢谢!
如有疑问,请使用反射器:)。 use关键字创建“ using”的作用域,直到该块结束为止。 在异步工作流程中使用时,如果对async关键字进行反糖处理,则会得到类似以下内容的内容:
Async.Bind(Async.FromBeginEnd(listener.BeginGetContext, listener.EndGetContext)
(fun context ->
use s = context.Response.OutputStream
let wr = new StreamWriter(s)
use disp = { new IDisposable with
member x.Dispose() =
printfn "Disposing..."
wr.Dispose() }
wr.Write("Test")
Async.ReturnFrom ( respondOut() )
)
现在,最后调用Async.ReturnFrom将继续递归调用该函数,如果将使用替换为“ C#using(){}”,其中}括号位于Async.ReturnFrom之后,则永远不会调用该dispose。
将使用部分包装在do块中应该可以解决问题:
let rec respondOut() = async {
let! context = Async.FromBeginEnd(listener.BeginGetContext, listener.EndGetContext)
do
use s = context.Response.OutputStream
let wr = new StreamWriter(s)
use disp = { new IDisposable with
member x.Dispose() =
printfn "Disposing..."
wr.Dispose() }
wr.Write("Test")
return! respondOut()
}
use
扩展到块的末尾,因此我希望在递归计算返回之后调用Dispose
(在这种情况下,因为它是无条件循环的,所以永远不会调用)。 如果您想更早地处置资源,则需要以某种方式界定use
绑定的范围。 也许像这样的事情会工作(我还没有尝试过):
let rec respondOut() = async {
let! context = Async.FromBeginEnd(listener.BeginGetContext, listener.EndGetContext)
do! async {
use s = context.Response.OutputStream
let wr = new StreamWriter(s)
use disp = { new IDisposable with
member x.Dispose() =
printfn "Disposing..."
wr.Dispose() }
wr.Write("Test")
}
return! respondOut()
}
我的猜测是,由于未使用disp
已在您的编译代码中对其进行了优化。 尝试在下一行添加printfn "%A" disp
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.