我的代码如下:
[HttpPost]
public ActionResult CustomerSearch(string firstName ...
{
...
try
{
var results = from t in db.Customers...
var custResults = results.Select(c=> new string[] { ... });
return this.Json(custResults );
}
catch (TimeoutException exc1)
{
return this.Json(new {error = "Search failed (timeout)"});
}
catch (System.Exception exc)
{ ... }
}
我通过将sql调用的超时设置为小(5s)来测试它。确实发生了异常,我可以在我的日志中看到它并且protected override void OnException
事件正在触发。但是TimeoutException
或Exception
的捕获量永远不会受到影响。我怀疑MVC是如何工作的,我不理解。
奇怪的是,如果我在return this.Json(custResults);
上设置断点,我可以毫无问题地通过该行。但是如果我在ToList()
上放置一个.Select(..)
,那么将抛出TimeoutException。在执行return语句后,MVC如何枚举结果集?
答案 0 :(得分:3)
Json
可能是一种惰性方法,因为它不会枚举给定的结果集。相反,它将结果集包装在另一个枚举器中。这意味着在MVC需要结果之前,SQL永远不会被执行。鉴于您的函数不执行枚举但MVC执行,这会导致异常发生在您无法将其包装在try / catch块中的情况。
正如您在帖子中提到的,添加ToList()会导致集合和存储的枚举进入某个位置,从而导致异常发生在您期望的位置。
答案 1 :(得分:0)
Select()调用将创建一个延迟(懒惰)枚举
http://msdn.microsoft.com/en-us/library/bb548891.aspx:
此方法通过使用延迟执行来实现。立即返回值是一个对象,它存储执行操作所需的所有信息。直到通过直接调用其GetEnumerator方法或在Visual C#中使用foreach或在Visual Basic中使用For Each来枚举对象时,才会执行此方法表示的查询。
执行ToList()或ToArray()将从中创建非延迟集合