假设我有以下内容:
private IEnumerable MyFunc(parameter a)
{
using(MyDataContext dc = new MyDataContext)
{
return dc.tablename.Select(row => row.parameter == a);
}
}
private void UsingFunc()
{
var result = MyFunc(new a());
foreach(var row in result)
{
//Do something
}
}
根据文档,linq的执行将推迟到我实际枚举结果,这发生在foreach的行中。但是,using语句应该在调用MyFunct()结束时强制可靠地收集对象。
实际上会发生什么,处理器何时运行和/或结果何时运行?
我唯一能想到的是延迟执行是在编译时计算的,所以实际的调用被编译器移动到foreach的第一行,导致using正确执行,但直到foreach行才运行?有没有一个大师可以帮助你?
编辑:注意:这段代码确实可以工作,我只是不明白如何工作。
我做了一些阅读,我意识到在我的代码中,我已经调用了ToList()扩展方法,它当然会枚举结果。勾选的答案的行为对于实际回答的问题是完全正确的。
抱歉造成任何混淆。
2条答案
按热度按时间htzpubme1#
我认为这根本行不通;
Select
被延迟,因此此时没有数据被消耗。但是,由于您已经释放了data-context(在离开MyFunc
之前),它将永远无法获取数据。一个更好的选择是将数据上下文传递给方法,这样消费者就可以选择生存期。另外,我建议返回IQueryable<T>
,以便消费者可以“合成”结果(即添加OrderBy
/Skip
/Take
/Where
等,并使其影响最终查询):更新:如果你(评论)不想推迟执行(即你不希望调用者处理数据上下文),那么你需要评估结果。您可以通过对结果调用
.ToList()
或.ToArray()
来缓冲值来实现这一点。如果你想在这种情况下保持它的延迟,那么你需要使用一个“迭代器块”:
这现在被推迟,而不传递数据上下文。
rryofs0p2#
我刚刚发布了这个问题的另一个延迟执行解决方案here,包括以下示例代码:
Use()
扩展方法本质上就像一个延迟的using
块: