[英]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.