2016-01-13 59 views
1

我目前使用LINQ到文件列表加載到XDocuments,就像這樣:LINQ僅選擇拋出IOException異常時可枚舉的看着

var fileNames = new List<string>(){ "C:\file.xml" }; 

var xDocs = fileNames.Select(XDocument.Load); 

var xDocs2 = xDocs.ToList(); // Crashes here  

如果我故意「鎖」與文件中的一個一個不同的進程,只有當我真正開始查看我已經生成的XDocuments時,也就是當ToList()被調用時,IOException纔會被拋出。

任何人都可以解釋爲什麼這是,以及如何最好地處理這個錯誤?如果可能,我想仍然可以訪問正在運行的XDocuments。

+0

什麼是異常消息。 – user1666620

+7

此處的關鍵字是'延期執行' – Jehof

+0

如何最好地處理這個錯誤是使用'foreach'循環而不是Linq - 特別是對於需要錯誤處理的任務。 –

回答

1

任何人都可以解釋爲什麼這是

正如許多人士指出,這是因爲所謂的延期許多LINQ方法的執行。對於instanse,所述Enumerable.Select方法documentation指出

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

Enumerable.ToListdocumentation包含

的ToList < TSource>(IEnumerable的< TSource>)方法部隊立即查詢評估,並返回一個包含查詢結果的列表。您可以將此方法追加到您的查詢中,以獲取查詢結果的緩存副本。

因此,在調用ToList時,XDocument.Load確實針對每個文件名執行。我想這涵蓋了爲什麼的一部分。

以及如何最好地處理這個錯誤?如果可能,我想仍然可以訪問正在運行的XDocuments。

我不知道該怎麼做在這種情況下「最佳」的意思,但如果你想忽略錯誤,包括「工作XDocuments」,那麼你可以使用這樣的事情

var xDocs = fileNames.Select(fileName => 
{ 
    try { return XDocument.Load(fileName); } 
    catch { return null; } 
}); 

,然後在處理列表時添加.Where(doc => doc != null)或者處理null文檔。

0

這就是爲什麼linq .Select是一個IEnumerable,如果您將IEnumerable設置爲List,則首先調用這些元素。然後你瀏覽一下你的所有元素。