Skip Ribbon Commands
Skip to main content

Robin | zevenseas | SharePoint Blog

:

The zevenseas Community > Blogs > Robin | zevenseas | SharePoint Blog > Posts > ContentIterator
April 06
ContentIterator

In SharePoint 2010, a new class has been introduced to loop through the various containers that can be found in the SharePoint object model (like SPSite, SPWeb, SPList, etc). It’s called the ContentIterator which is a part of the Microsoft.Office.Server.Utilities namespace, by making use of this iterator instead of looping through the objects in a regular ‘for-each’ loop you are ‘safe’ by not stressing out the database. Really? How do you know? Well it states in this on the MSDN page :

Provides an interface to iterate through SharePoint objects (such as sites, lists, and list items) to regulate the amount of data transferred. This is especially important for queries on large lists or Web farms so that the load put on the database is not excessive.

(and they are probably right.. right? ;) So how do we use it then? I’ve broken it down into all the various containers that SharePoint has to offer:

Looping through sites:

SPWebApplication webApplication = SPWebApplication.Lookup(new Uri("http://sp2010"));
ContentIterator contentIterator = new ContentIterator();
contentIterator.ProcessSites(webApplication.Sites,
    siteProcessor:
    delegate(SPSite _site)
    {
        using (_site)
        { 
            //do something awesome with the site
        }
    },
    errorCallout: (ContentIterator.SiteProcessorErrorCallout)
    delegate(SPSite _site, Exception error)
    {
        return true;
    }
);

Looping through webs:

ContentIterator contentIterator = new ContentIterator();
contentIterator.ProcessSite(site,
webProcessor:
    delegate(SPWeb _web)
    {
        using (_web)
        {
            //do something awesome with the web
        }
    },
errorCallout:
    delegate(SPWeb _web, Exception error)
    {
        return true;
    }
);

Looping through lists:

ContentIterator contentIterator = new ContentIterator();
contentIterator.ProcessLists(web.Lists,
    listProcessor: 
        delegate(SPList _list)
        {
            //do something awesome with the list
        },
    errorCallout: 
        delegate(SPList _list, Exception error) 
        { return true; }
);
       

Looping through listitems (the most basic way):

ContentIterator contentIterator = new ContentIterator();
                contentIterator.ProcessListItems(web.Lists["ListName"],
                itemProcessor: delegate(SPListItem item)
                {
                    //do something awesome with the item
                },
                errorCallout: delegate(SPListItem item, Exception error)
                {
                    return true;
                });

 

Performance

The one thing that struck my mind was.. “If I use this, is the performance better as well?”. To answer that question, I created some fairly simple but ‘heavy’ foreach loops like:

foreach (SPListItem item in web.Lists["Big List"].Items)
{ 
    
}

and used the Stopwatch to measure the miliseconds on a list that contained 1000 items. Below is a table that shows how long it took while repeating the loop 19 times for both iterators.

ContentIterator ‘vanilla’ Foreach
199 95
108 97
110 96
106 98
115 106
107 88
103 90
105 309
109 101
106 143
109 106
107 106
108 101
118 100
122 100
105 89
107 92
106 100
118 102

As you can see, the ContentIterator is not faster than the ‘expensive' foreach loop. Yet, the question remains.. when do you use ContentIterator? I think a good use would be to use this in timerjobs  to minimize the impact of the servers while iterating through the objects. Otherwise, I still have no suggestions up until now but I will look into it more and more, if you have any idea please let me know ;)

Comments

Chris O'Brien

As I was reading this I was thinking "there's gotta be a performance hit for that extra checking", so I'm glad you took a look.

I agree it could be appropriate to use this at least for background tasks - could be a step towards governing resources there. Although one consideration might be that even if you're using all the items in a collection, you might find a query which is faster than iteration in any case.

Good info mate :)
System Account on 06/04/2010 15:39

Robin

Yes, though there are a lot more calls you can do to retrieve listitems using the ContentIterator (by using the SPQuery for example as a parameter)

Was just wondering as well if we need to dispose the SPWeb and SPSite objects. I looked what's going on behind the scenes with Reflector and it does close the objects. Don't know if that's enough for the garbage collector to dispose the objects as well.
System Account on 06/04/2010 22:59

Jaap Vossers

the TimerJobUtility class, which inherits from ContentIterator, looks quite interesting as well!

http://msdn.microsoft.com/en-us/library/microsoft.office.server.utilities.timerjobutility_members(v=office.14).aspx
System Account on 04/05/2010 09:04

Tom Van Gaever

We received an SPQueryThrottledException while using the content iterator on a list with more than 100K items

http://tomvangaever.be/wordpress/2011/05/contentiterator-very-large-lists/
 on 06/05/2011 09:28
 

 Statistics

 
Views: 5596
Comments: 3
Tags:
Published:1695 Days Ago