Reputation: 46569
I have code that looks like this:
[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)
{ ... }
}
I test this by setting the timeout on the sql call to something small (5s). The exception is certainly happening, I can see it in my logs and the protected override void OnException
event is firing. But the catch for the TimeoutException
or Exception
never gets hit. I suspect there's something about how MVC works that I'm not understanding.
The peculiar thing is that if I put a breakpoint on the return this.Json(custResults);
I can pass that line with no problem. But if I put a ToList()
on the .Select(..)
then the TimeoutException will be thrown. How can MVC enumerate a result set after a return statement has been executed?
Upvotes: 2
Views: 193
Reputation: 392903
The Select() call will create a deferred (lazy) enumeration
http://msdn.microsoft.com/en-us/library/bb548891.aspx:
This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.
Doing ToList() or ToArray() will create a non-deferred collection out of it
Upvotes: 0
Reputation: 19203
Json
is likely a lazy method, in that it does not enumerate the result set given. Instead it wraps the result set in another enumerator. This means that until the MVC needs the results the SQL is never executed. Given that your functions do not perform the enumeration but MVC does, this causes the exception to happen where you cannot wrap it in a try/catch block.
As you mentioned in your post added a ToList() will cause the enumeration of the set and storage into a location, causing the exception to happen where you expect it to.
Upvotes: 3