2011-06-27 39 views
2

我有代碼看起來像這樣:MVC枚舉結果*後*某種形式的返回語句?

[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調用的東西不多(5秒)的超時對此進行測試。例外情況肯定發生,我可以在我的日誌中看到它,並且事件正在發射。但是TimeoutExceptionException的捕獲從未受到影響。我懷疑MVC是如何工作的,而我並不理解。

特別的是,如果我在return this.Json(custResults);上放置了一個斷點,我可以毫無問題地傳遞該行。但是,如果我在.Select(..)上放置ToList(),則會拋出TimeoutException。在執行return語句之後,MVC如何枚舉結果集?

+1

哪裏嘗試捕捉與相關聯? – Bueller

+0

我認爲你的漁獲投擲錯誤,你可以嘗試添加斷點來驗證這一點。 – Jethro

+1

爲了簡潔,假設TRY已被忽略,我認爲這可能是一個deyled執行問題。 linq語句在使用之前不會實際運行。要測試catch只需把Throw new Exection(「test」);在方法的頂部,看看它是否被捕獲。 – HitLikeAHammer

回答

3

Json可能是一個懶惰的方法,因爲它沒有枚舉給定的結果集。相反,它將結果集包裝在另一個枚舉器中。這意味着,直到MVC需要結果,SQL永遠不會被執行。鑑於你的函數不執行枚舉,但MVC會這樣做,這會導致異常發生在你無法將它包裝在try/catch塊中的地方。

正如你在你的文章中提到的,添加一個ToList()會導致集合和存儲的枚舉到一個位置,導致異常發生在你期望的位置。

+0

我怎麼能確定它是否是一個懶惰的方法?我沒有看到它的遺傳中指出的任何東西。 – jcollum

+0

@jcollum:我會親自檢查結果的類型。它返回一個包裝在提供的對象周圍的JsonResult對象。 JsonResult只是存儲對象(作爲對象),所以在這一點上它不會執行任何分析。這意味着ActionResult正在程序中的某個位置處理。 (順便說一下,我在IL反彙編程序中打開了Microsoft.Web.Mvc.dll,但有時您可以從文檔中找出它)。 – Guvante

0

的select()調用將創建一個延遲(懶)枚舉

http://msdn.microsoft.com/en-us/library/bb548891.aspx

這種方法是通過使用延遲執行實現。即時返回值是存儲執行操作所需的所有信息的對象。直到通過直接調用其GetEnumerator方法或使用Visual C#中的foreach或Visual Basic中的For Each來枚舉對象,纔會執行此方法表示的查詢。

做ToList()或ToArray的()將創建一個非延期收集出來的