2014-02-25 85 views
1

我正在使用PDFNet庫從PDF中提取對象,然後使用OCR。我實例化我Elements對象:IEnumerable執行中斷foreach

public class Processor 
{ 
    public static int Main(string[] args) 
    { 
     Elements pdfPageElements = new Elements(pdfPage); 
     ... 

構造函數(在一個單獨的類)看起來像

internal class Elements : IEnumerator<Element>, IEnumerable<Element> 
{ 
    private readonly int _position; 
    private readonly ElementReader _pdfElements; 
    private Element _current; 

    public Elements(Page currentPage) 
    { 
     _pdfElements = new ElementReader(); 
     _pdfElements.Begin(currentPage); 
     _position = 0; 
    } 

    ... 

實例pdfPageElements後,我回到main()和使用LINQ遍歷集合項目以獲取我想要的PDF對象(在本例中爲圖像)。

var pdfPageImages = (from e in pdfPageElements 
        where 
         (e.GetType() == Element.Type.e_inline_image || 
          e.GetType() == Element.Type.e_image) 
        select e); 

的PDFNet SDK實現的MoveNext()作爲方法如下:

public bool MoveNext() 
{ 
    if ((_current = _pdfElements.Next()) != null) 
    { 
     return true; 
    } 
    else 
    { 
     _pdfElements.Dispose(); 
     return false; 
    } 
} 

pdfPageImages是很好instatiatied; Console.WriteLine(pdfPageImages.Count());爲我的測試PDF返回適當數量的圖像。

但是當我通過foreach loop我得到下面的異常發送pdfPageImages

pdftron.Common.PDFNetException: Unknown exception. 
at pdftron.PDF.ElementReader.Next() 
at pdftron.Elements.MoveNext() 
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext() 
at DM_PDFProcessor.Processor.Main(String[] args) 

這或許值得指出的是詮釋他PDFNet文檔它指出:

Every call to ElementReader::Next() destroys the current Element. 
Therefore, an Element becomes invalid after subsequent 
ElementReader::Next() operation. 

然而,一旦元素被讀入IEnumerable pdfPageImages,它應該是無限期迭代的(從我的有限理解)。


注意,集合中的元素是絕對不爲空。任何想法,爲什麼我不斷得到例外?

+1

它實現了'IEnumerable的'*和*'的IEnumerator '事實幾乎總是一個不好的跡象,除非它已經使用迭代器塊來實現(在這種情況下編譯器會做正確的事情)。聽起來像元素類被設計破壞了。 –

+0

如果Count()方法迭代集合(如果沒有Count屬性或類似的東西時它會這樣做),那麼ElementReader :: Next方法會在每個元素被訪問後銷燬它。因此,下次嘗試迭代集合時,元素不再有效。 –

回答

3

注意

var pdfPageImages = (from e in pdfPageElements 
        where 
         (e.GetType() == Element.Type.e_inline_image || 
          e.GetType() == Element.Type.e_image) 
        select e); 

是懶洋洋地評估。也就是說,每次pdfPageImages被枚舉,pdfPageElements也被枚舉。因此,如果Elements類構建,這樣的實例只能使用一次,不拋出列舉,你可能想緩存查詢結果:

var pdfPageImages = (from e in pdfPageElements 
        where 
         (e.GetType() == Element.Type.e_inline_image || 
          e.GetType() == Element.Type.e_image) 
        select e).ToList();