【发布时间】:2012-12-28 16:16:42
【问题描述】:
我已将有问题的代码隔离到此函数(使用 ASP.NET 的 Membership 类):
let dbctx = DBSchema.GetDataContext()
let rec h1 (is2_ : int) (ie2_ : int) : unit =
match is2_ >= ie2_ with
| true ->
let st2 = query {
for row in dbctx.Tbl_Students do
where (row.Id = is2_)
head}
let l2 =
Membership.FindUsersByEmail (st2.Email_address)
|> Seq.cast<_>
|> Seq.length
match l2 >= 1 with
| true ->
()
| false ->
Membership.CreateUser (st2.Email_address, password, st2.Email_address)
|> ignore
h1 (is2_ - 1) ie2_
| false ->
()
在5626 的h1 迭代之后,我得到了一个System.OutOfMemoryException。但是我系统的内存消耗只有20 percent。 (我有一台非常强大的 16 GB 机器。)
为什么上面的函数会溢出堆栈?不是递归写成tail吗?
提前感谢您的帮助。
【问题讨论】:
-
您是否在调试模式下运行?如果是这样,则禁用尾调用。在发布模式下尝试您的代码。
-
我会用
Seq.isEmpty重写最后一部分。无需枚举整个序列。 -
@Daniel 是这样吗?我在项目中有许多其他尾递归函数,它们在相同的调试模式下遍历更深而不会引发错误。不过,我会检查这是否是问题所在。感谢您的建议。
-
@pad,感谢您的建议。我已经进行了更改(在我的实际代码中)。
-
是否有可能是数据上下文被重用和积累数据。我希望这条线是 - 让 dbctx() = DBSchema.GetDataContext() 代替,每次都创建一个新的数据上下文。
标签: f# asp.net-membership tail-recursion tail-call-optimization