我有一个代理,我设置在后台做一些数据库工作.实现看起来像这样:
let myAgent = MailboxProcessor<AgentData>.Start(fun inbox ->
let rec loop =
async {
let! data = inbox.Receive()
use conn = new System.Data.SqlClient.SqlConnection("...")
data |> List.map (fun e -> // Some transforms)
|> List.sortBy (fun (_,_,t,_,_) -> t)
|> List.iter (fun (a,b,c,d,e) ->
try
... // Do the database work
with e -> Log.error "Yikes")
return! loop
}
loop)
Run Code Online (Sandbox Code Playgroud)
有了这个,我发现如果在一段时间内多次调用它,我会开始使SqlConnection对象堆积而不是被丢弃,最终我会在连接池中用尽连接(我没有确切的指标)有多少"几个",但连续两次运行集成测试套件总是会导致连接池运行干燥).
如果我use
改为a,using
则事情处理得当,我没有问题:
let myAgent = MailboxProcessor<AgentData>.Start(fun inbox ->
let rec loop =
async {
let! data = inbox.Receive() …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Windows服务调试生产问题,一旦多个并发连接处于活动状态,该服务就会迅速崩溃.通过核心转储和DebugDiag的神奇之处,我发现有一个挂起的GC操作,直到几个Preemptive GC禁用的线程完成了他们的工作才能启动.
以下是来自WinDbg的示例线程转储,显示了有问题的线程:
26 6e 1444 00..440 8009222 Disabled 00..200:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
27 c1 1a0c 00..fe0 8009222 Disabled 00..e90:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
28 b5 17bc 00..6f0 8009222 Disabled 00..268:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
29 89 1f1c 00..ab0 8009222 Disabled 00..a30:00..f88 00..7a0 0 MTA (Threadpool Completion Port)
30 ac 2340 00..f70 8009220 Disabled 00..d00:00..d08 00..7a0 1 MTA (GC) (Threadpool Completion Port)
31 88 1b64 00..fd0 8009220 Enabled 00..b28:00..b48 00..7a0 0 MTA (Threadpool …
Run Code Online (Sandbox Code Playgroud)